测试值是否为函数

测试值是否为函数

问题描述:

我需要测试窗体的值onsubmit是否为函数。格式通常是onsubmit="return valid();"。有没有办法判断这是一个函数,如果它是可调用的?使用typeof只是返回它是一个字符串,这对我没有多大帮助。测试值是否为函数

编辑:当然,我明白“return valid();”是一个字符串。我已将replace记录为“valid();”,甚至“valid()”。我想知道这些是否是一种功能。

编辑:下面是一些代码,这可能有助于解释我的问题:

$("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; 
    } 
}); 

编辑2:这里是新的代码。看来我仍然必须使用eval,因为调用form.submit()不会触发现有的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; 
    } 
}); 

关于可能如何做得更好的建议?

我更换提交按钮与 锚链接。由于调用 form.submit()不会激活 onsubmit,我正在查找它,并自行评估它。但我想 检查功能是否存在 只是eval()有什么。 - 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> 

编辑:缺少参数f在功能testOnsubmitAndSubmit

您是否分配onsubmit HTML属性或JavaScript中分配给它上面应该不论工作:

document.forms['theForm'].onsubmit = onsubmitHandler; 

这样一个简单的检查将让你知道,如果它存在/定义:

if (this.onsubmit) 
{ 
    // do stuff; 
} 
+5

这是行不通的。当onsubmit也是非空字符串时,if将断言为TRUE。 – Seb 2009-04-28 14:48:59

+1

一个可怕的测试方法,如果某个东西是一个函数 - 如前所述,并且更清晰:任何“真理”都会导致此代码“做东西”,而这可能不是预期的结果。如果将this.onsubmit设置为值5或“hello”或JavaScript中的任何其他值为true的值,您将会遇到意外的行为。 – 2009-04-28 20:22:20

+0

问题的主题是询问如何检查是否存在问题。这就是我所说的 - 不多也不少。 – Kon 2009-04-29 20:33:19

确保您的实际功能,而不是一个字符串的typeof呼吁:

function x() { 
    console.log("hi"); 
} 

typeof "x"; // returns "string" 

typeof x; // returns "function" 

什么浏览器是否在使用?

alert(typeof document.getElementById('myform').onsubmit); 

这给了我在IE7和FireFox中的“function”。

+0

即使你的onsubmit是“返回有效();”? – 2009-04-28 15:23:58

+1

是的 - 不要忘记,你不能在功能之外“返回”。 – Greg 2009-04-28 16:01:45

+0

只要定义为HTML属性,form.onsubmit将始终是一个函数。看到我的答案。 – 2009-04-28 17:39:53

你可以尝试修改this technique,以满足您的需求:

function isFunction() { 
    var functionName = window.prompt('Function name: '); 
    var isDefined = eval('(typeof ' + functionName + '==\'function\');'); 
    if (isDefined) 
    eval(functionName + '();'); 
    else 
    alert('Function ' + functionName + ' does not exist'); 
} 
function anotherFunction() { 
    alert('message from another function.'); 
} 

尝试

if (this.onsubmit instanceof Function) { 
    // do stuff; 
} 

好,"return valid();"一个字符串,所以这是正确的。

如果你想检查是否有代替附加的功能,你可以试试这个:

formId.onsubmit = function(){ /* */ } 

if(typeof formId.onsubmit == "function"){ 
    alert("it's a function!"); 
} 

如果它是一个字符串,你可以假设/希望它的形式总是

return SomeFunction(arguments); 

解析为函数的名称,然后看看是否函数被定义使用

if (window[functionName]) { 
    // do stuff 
} 

if (window.onsubmit) { 
    // 
    } else { 
    alert("Function does not exist."); 
    } 

你可以简单地用一个三元运营商使用typeof运营商一起简称:

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

如果我们把它并返回它的返回值的函数,否则直接返回true

编辑:

我不太清楚你真正想做什么,但我会尽力解释可能发生的事情。

当你在你的html中声明你的onsubmit代码时,它会变成一个函数,因此它可以从JavaScript“世界”中调用。这意味着这两种方法是等价的:

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

这两个都是函数,都是可调用的。您可以使用typeof运算符来测试其中的任何运算符,它们应该具有相同的结果:"function"

现在,如果您通过JavaScript为“onsubmit”属性指定一个字符串,它仍然是一个字符串,因此无法调用。请注意,如果您将typeof运算符应用于此运算符,则会得到"string"而不是"function"

我希望这可以澄清一些事情。再次,如果你想知道这样的属性(或任何标识符)是一个函数并且可以调用,那么typeof运营商应该做的。尽管我不确定它是否能够在多个帧中正常工作。当定义为HTML形式元素的属性

干杯

form.onsubmit将始终是一个函数。它是附加到HTML元素的某种匿名函数,其中这个指针绑定到该FORM元素,并且还有一个名为event的参数,该参数将包含有关submit事件的数据。

在这些情况下,我不明白你是如何得到一个字符串作为typeof操作的结果。你应该提供更多的细节,更好的代码。

编辑(如你的第二个编辑的响应):

我相信不管连接到HTML属性的处理程序将执行上面的代码。此外,你可以尝试以某种方式阻止它,但是,看起来FF 3,IE 8,Chrome 2和Opera 9首先执行HTML属性处理程序,然后是附加的属性处理程序(我没有使用jQuery进行测试虽然,但与addEventListener和attachEvent)。所以...你想要完成什么?

顺便说一句,你的代码不工作,因为你的正则表达式会提取字符串“valid();”,这绝对不是一个函数。

我认为混淆的根源是节点的属性和相应的属性之间的区别。

您使用:

$("a.button").parents("form").attr("onsubmit") 

你直接读取onsubmit属性的值(必须是一个字符串)。相反,你应该访问节点的onsubmit财产

$("a.button").parents("form").prop("onsubmit") 

下面是一个简单的测试:

<form id="form1" action="foo1.htm" onsubmit="return valid()"></form> 
<script> 
window.onload = function() { 
    var form1 = document.getElementById("form1"); 

    function log(s) { 
     document.write("<div>" + s + "</div>"); 
    } 

    function info(v) { 
     return "(" + typeof v + ") " + v; 
    } 

    log("form1 onsubmit property: " + info(form1.onsubmit)); 
    log("form1 onsubmit attribute: " + info(form1.getAttribute("onsubmit"))); 
}; 
</script> 

这产生了:

 
form1 onsubmit property: (function) function onsubmit(event) { return valid(); } 
form1 onsubmit attribute: (string) return valid() 

你可以始终在JavaScript博客上使用typeOf函数之一,例如Chris West's。使用的定义,如为typeOf()功能下面将工作:

function typeOf(o){return {}.toString.call(o).slice(8,-1)} 

此功能(在全局命名空间中声明,可以用这样的:

alert("onsubmit is a " + typeOf(elem.onsubmit)); 

如果它是一个功能,“功能”将使用基于字符串的无功返回。如果它是一个字符串,“字符串”将被退回。其他可能的值显示here

// This should be a function, because in certain JavaScript engines (V8, for 
// example, try block kills many optimizations). 
function isFunction(func) { 
    // For some reason, function constructor doesn't accept anonymous functions. 
    // Also, this check finds callable objects that aren't function (such as, 
    // regular expressions in old WebKit versions), as according to EcmaScript 
    // specification, any callable object should have typeof set to function. 
    if (typeof func === 'function') 
     return true 

    // If the function isn't a string, it's probably good idea to return false, 
    // as eval cannot process values that aren't strings. 
    if (typeof func !== 'string') 
     return false 

    // So, the value is a string. Try creating a function, in order to detect 
    // syntax error. 
    try { 
     // Create a function with string func, in order to detect whatever it's 
     // an actual function. Unlike examples with eval, it should be actually 
     // safe to use with any string (provided you don't call returned value). 
     Function(func) 
     return true 
    } 
    catch (e) { 
     // While usually only SyntaxError could be thrown (unless somebody 
     // modified definition of something used in this function, like 
     // SyntaxError or Function, it's better to prepare for unexpected. 
     if (!(e instanceof SyntaxError)) { 
      throw e 
     } 

     return false 
    } 
} 

作为例子和使用instanceof 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(); 
}