测试值是否为函数


88

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

编辑:当然,我知道“返回有效的();” 是一个字符串。我将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()不会触发现有的onsubmit。

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;
    }
} );

关于如何更好地做到这一点的建议?

Answers:


85

我用定位链接替换了一个提交按钮。由于调用form.submit()不会激活onsubmit,因此我正在查找它,并自己对其进行eval()。但是我想在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>

编辑:函数testOnsubmitAndSubmit中缺少参数f

无论您是分配onsubmitHTML属性还是在JavaScript中分配属性,上述方法都应该起作用:

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

1
f.onsubmit中的f来自哪里?
艺术

f是一个表单实例。您将其作为参数传递给testOnsubmitAndSubmit函数。(我知道这个问题已经很老了,但也许我的回答会为某人节省一些时间:))
zeroos 2012年

63

尝试

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

7
那只是一个例子。您可以将其更改为button.onsubmit instanceof Function
artemb

13

您可以简单地将typeof运算符与三元运算符一起使用:

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

如果它是一个函数,我们调用它并返回它的返回值,否则返回 true

编辑:

我不太确定您真正想做什么,但是我将尽力解释可能发生的情况。

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

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

这两个都是函数,并且都是可调用的。您可以使用typeof运算符测试任何一个,这些运算符应产生相同的结果:"function"

现在,如果您通过JavaScript将字符串分配给“ onsubmit”属性,则它将保留为字符串,因此无法调用。请注意,如果typeof对它应用运算符,则会得到"string"而不是"function"

我希望这可以澄清一些事情。再说一次,如果您想知道这样的属性(或该事件的任何标识符)是否是一个函数并且是可调用的,typeof操作员应该解决这个问题。尽管我不确定它是否可以在多个帧中正常工作。

干杯


我需要在onsubmit之外对此进行测试。
Glen Solsberry,2009年

5

你使用的是什么浏览器?

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

这使我function在IE7和FireFox中成为了“ ”。


即使您的onsubmit是“ return valid();”?
Glen Solsberry,2009年

1
是的-不要忘记,您不能在函数外部“返回”。
格雷格,

只要将form.onsubmit定义为HTML属性,它将始终是一个函数。看我的答案。
Ionuț G. Stan,

4

以基于字符串的变量为例并利用 instanceof Function 您注册函数..分配变量...检查变量是函数的名称...进行预处理...将函数分配给新的var ...然后调用函数。

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

2
您实际上不需要那个fn变量,可以只使用window [value]();。
Lajos Meszaros

1
是的,我知道,但是我也意识到,通常可以很容易地理解长格式,因为无论如何,这都是一个学习您的输入的网站,无论如何@LajosMeszaros
CrandellWS

3

确保在实际函数上调用typeof,而不是字符串文字:

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

typeof "x"; // returns "string"

typeof x; // returns "function"

3

您可以尝试修改此技术以适合您的需求:

 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.');
 }

2

当form.onsubmit定义为form元素的HTML属性时,它将始终是一个函数。这是附加到HTML元素的某种匿名函数,该元素具有与FORM元素绑定的this指针,还具有名为的参数event,该参数将包含有关Submit事件的数据。

在这种情况下,我不明白如何通过typeof操作获得字符串。您应该提供更多的细节,更好的代码。

编辑(作为对第二次编辑的回应):

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

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


2

如果是字符串,您可以假设/希望它始终是以下形式

return SomeFunction(arguments);

解析函数名称,然后查看该函数是否使用

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

我也要添加此分辨率...只是记得在文档/窗口级别注册该功能
CrandellWS 2014年

1

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

如果要检查是否附加了功能,可以尝试以下操作:

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

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

1

我认为问题的根源是一个节点之间的区别属性和相应的属性

您正在使用:

$("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属性:(函数)功能onsubmit(event){return valid(); }
form1 onsubmit属性:(字符串)返回有效值()

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


0

您始终可以在JavaScript博客(例如Chris West's)上使用typeOf函数之一。对typeOf()函数使用如下定义可以正常工作:

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

此函数(在全局名称空间中声明,可以像这样使用:

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

如果是函数,则将返回“函数”。如果是字符串,将返回“ String”。其他可能的值在此处显示。


0
// 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
    }
}

-3

像这样的简单检查将让您知道它是否存在/已定义:

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

6
这行不通。如果onsubmit也为非空字符串,则if也会断言为TRUE。
勒布

1
一种可怕的测试方式,即是否有某种功能是正确的-如所示,并且更清楚:任何“真实”的操作都会导致该代码“执行操作”,而这可能并非预期的结果。如果将this.onsubmit的值设置为5或“ hello”或JavaScript中其他任何值为true的值,您将得到意外的行为。
詹森·邦廷

问题的主题询问如何检查是否存在某些东西。那就是我的建议-不多也不少。

并非如此-原始帖子说他“需要测试表单的onsubmit的值是否是一个函数”。您的条件不是this.onsubmit是否为一个函子,您的测试只是询问this.onsubmit是否为“真”
Jason Bunting 2009年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.