Testing if value is a function

2019-01-30 21:02发布

I need to test whether the value of a form's onsubmit is a function. The format is typically onsubmit="return valid();". Is there a way to tell if this is a function, and if it's callable? Using typeof just returns that it's a string, which doesn't help me much.

EDIT: Of course, I understand that "return valid();" is a string. I've replaced it down to "valid();", and even "valid()". I want to know if either of those is a function.

EDIT: Here's some code, which may help explain my problem:

$("a.button").parents("form").submit(function() {
    var submit_function = $("a.button").parents("form").attr("onsubmit");
    if ( submit_function && typeof( submit_function.replace(/return /,"") ) == 'function' ) {
        return eval(submit_function.replace(/return /,""));
    } else {
        alert("onSubmit is not a function.\n\nIs the script included?"); return false;
    }
} );

EDIT 2: Here's the new code. It seems that I still have to use an eval, because calling form.submit() doesn't fire existing onsubmits.

var formObj = $("a.button").parents("form");
formObj.submit(function() {
    if ( formObj[0].onsubmit && typeof( formObj.onsubmit ) == 'function' ) {
        return eval(formObj.attr("onsubmit").replace(/return /,""));
    } else {
        alert("onSubmit is not a function.\n\nIs the script included?");
        return false;
    }
} );

Suggestions on possibly how to do this better?

15条回答
看我几分像从前
2楼-- · 2019-01-30 21:34
  if ( window.onsubmit ) {
     //
  } else {
     alert("Function does not exist.");
  }
查看更多
女痞
3楼-- · 2019-01-30 21:37

You could simply use the typeof operator along with a ternary operator for short:

onsubmit="return typeof valid =='function' ? valid() : true;"

If it is a function we call it and return it's return value, otherwise just return true

Edit:

I'm not quite sure what you really want to do, but I'll try to explain what might be happening.

When you declare your onsubmit code within your html, it gets turned into a function and thus its callable from the JavaScript "world". That means that those two methods are equivalent:

HTML: <form onsubmit="return valid();" />
JavaScript: myForm.onsubmit = function() { return valid(); };

These two will be both functions and both will be callable. You can test any of those using the typeof operator which should yeld the same result: "function".

Now if you assign a string to the "onsubmit" property via JavaScript, it will remain a string, hence not callable. Notice that if you apply the typeof operator against it, you'll get "string" instead of "function".

I hope this might clarify a few things. Then again, if you want to know if such property (or any identifier for the matter) is a function and callable, the typeof operator should do the trick. Although I'm not sure if it works properly across multiple frames.

Cheers

查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-30 21:44

using a string based variable as example and making use instanceof Function You register the function..assign the variable...check the variable is the name of function...do pre-process... assign the function to new var...then call the function.

function callMe(){
   alert('You rang?');
}

var value = 'callMe';

if (window[value] instanceof Function) { 
    // do pre-process stuff
    // FYI the function has not actually been called yet
    console.log('callable function');
    //now call function
   var fn = window[value];
   fn();
}
查看更多
狗以群分
5楼-- · 2019-01-30 21:46

form.onsubmit will always be a function when defined as an attribute of HTML the form element. It's some sort of anonymous function attached to an HTML element, which has the this pointer bound to that FORM element and also has a parameter named event which will contain data about the submit event.

Under these circumstances I don't understand how you got a string as a result of a typeof operation. You should give more details, better some code.

Edit (as a response to your second edit):

I believe the handler attached to the HTML attribute will execute regardless of the above code. Further more, you could try to stop it somehow, but, it appears that FF 3, IE 8, Chrome 2 and Opera 9 are executing the HTML attribute handler in the first place and then the one attached (I didn't tested with jQuery though, but with addEventListener and attachEvent). So... what are you trying to accomplish exactly?

By the way, your code isn't working because your regular expression will extract the string "valid();", which is definitely not a function.

查看更多
Deceive 欺骗
6楼-- · 2019-01-30 21:50

If it's a string, you could assume / hope it's always of the form

return SomeFunction(arguments);

parse for the function name, and then see if that function is defined using

if (window[functionName]) { 
    // do stuff
}
查看更多
相关推荐>>
7楼-- · 2019-01-30 21:51

I'm replacing a submit button with an anchor link. Since calling form.submit() does not activate onsubmit's, I'm finding it, and eval()ing it myself. But I'd like to check if the function exists before just eval()ing what's there. – gms8994

<script type="text/javascript">
function onsubmitHandler() {
    alert('running onsubmit handler');
    return true;
}
function testOnsubmitAndSubmit(f) {
    if (typeof f.onsubmit === 'function') {
        // onsubmit is executable, test the return value
        if (f.onsubmit()) {
            // onsubmit returns true, submit the form
            f.submit();
        }
    }
}
</script>

<form name="theForm" onsubmit="return onsubmitHandler();">
<a href="#" onclick="
    testOnsubmitAndSubmit(document.forms['theForm']);
    return false;
"></a>
</form>

EDIT : missing parameter f in function testOnsubmitAndSubmit

The above should work regardless of whether you assign the onsubmit HTML attribute or assign it in JavaScript:

document.forms['theForm'].onsubmit = onsubmitHandler;
查看更多
登录 后发表回答