Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有办法判断javascript函数是否已返回?_Javascript_Function_Return_Return Value_Undefined - Fatal编程技术网

有没有办法判断javascript函数是否已返回?

有没有办法判断javascript函数是否已返回?,javascript,function,return,return-value,undefined,Javascript,Function,Return,Return Value,Undefined,我目前正在编写一些代码来包装用户编写的JavaScript函数,并且在逻辑中遇到了一个点,如果所讨论的函数从未返回值,即从未计算过return关键字,我希望触发一个特定的行为 目前,我假设如果函数返回undefined,它就没有返回,但是这并不是严格正确的,因为函数总是可以返回undefined,或者返回未定义属性的值 通过函数调用,您总是可以知道由于arguments.length属性使用了多少参数,我想知道是否有人知道函数返回值的类似技巧 那么,是否可以区分a、b甚至c的返回值之间的差异 v

我目前正在编写一些代码来包装用户编写的JavaScript函数,并且在逻辑中遇到了一个点,如果所讨论的函数从未返回值,即从未计算过
return
关键字,我希望触发一个特定的行为

目前,我假设如果函数返回
undefined
,它就没有返回,但是这并不是严格正确的,因为函数总是可以
返回undefined
,或者返回未定义属性的值

通过函数调用,您总是可以知道由于
arguments.length
属性使用了多少参数,我想知道是否有人知道函数返回值的类似技巧

那么,是否可以区分
a
b
甚至
c
的返回值之间的差异

var a = function(){  };
var b = function(){ return undefined; };
var c = function(){ if(1){}else{return undefined;}; };

将函数留空也将返回未定义的值,因此a、b和c都将返回相同的值


实现这类功能的唯一方法是在函数本身中设置某种标志,但我猜您希望能够独立于实际函数的实现来实现这一点。

无法区分这两者之间的区别


如果您真的想,您可以尝试分析函数的源代码并确定它是否有任何返回语句,如果没有,则假定它不会返回值。当然,要确定一个函数是否有时返回,而其他函数是否返回(例如if块中的return语句)

不,您无法通过跨浏览器可靠地判断函数是否仅通过到达其代码末尾、使用
return
不带值或使用
return undefined
返回。这在本规范的第1部分中有所涉及


这里的另一个答案建议您可以通过分析函数的源代码来实现。然而,没有标准的机制来做到这一点。尽管几乎所有的浏览器都可以从
函数#toString
中获得某种形式的源代码,但有些浏览器没有(大部分是移动浏览器),并且规范中也没有对其进行定义。但是,如果您有一组您支持的浏览器,并且它们都有,这将是您唯一的实际选择-但即使这样,您也不一定知道函数中采用了哪个代码分支。

您只能知道是否通过包装器调用函数,但我不确定这是否适合您的用例

function invoker(f) {
    var actualFunc = f,
        invokeCount = 0;

    function invoke() {
        invokeCount = invokeCount +1;
        return actualFunc.apply(this, arguments);
    }

    function invoked() {
       return invokeCount;
    }

    return {
      invoke: invoke,
      invoked: invoked
    };
}

var a = function(){  };
var b = function(){ return undefined; };
var c = function(){ if(1){}else{return undefined;}; };

var ainvoker = new invoker(a);    

alert(ainvoker.invoke());
alert(ainvoker.invoked());

这是疯狂的,绝对不推荐,它创建函数的副本,修改函数体并使用
eval

function returnProxy(func,args) {
    var returnFlag = Math.random()+"";

    // create new function based on passed function body
    var fullFuncBody = func.toString();
    var tmpFuncStr = "function  "+ fullFuncBody.substr(fullFuncBody.indexOf("("));

    tmpFuncStr = tmpFuncStr.substr(0,tmpFuncStr.length-1)+"\nreturn '"+returnFlag+"'}";

    var tmpFunc;
    eval("tmpFunc = "+tmpFuncStr); // really bad things

    var funcOut = tmpFunc.apply(this,args);

    return {
        out: (funcOut == returnFlag) ? undefined : funcOut,
        returned: (returnFlag != funcOut)
    }
}
假设你有这样一个函数

function someFunction(action) {
    switch(action) {
        case 1:
            return undefined;
        case 2:
            return "hello";
    }
}
您可以像这样使用代理函数:

returnProxy(someFunction,[1]); // instead of calling someFunction(1)
第一个参数是函数本身,第二个参数是参数数组

返回值将是一个具有两个属性的对象,
out
包含函数结果,
returned
是一个布尔值,指示函数是否返回

示例输出

returnProxy(someFunction,[1]); // {out: undefined, returned: true}
returnProxy(someFunction,[2]); // {out: "hello", returned: true}
returnProxy(someFunction,[3]); // {out: undefined, returned: false} 

我认为这是不可能的。我很好奇:用例是什么?你为什么关心a、b或c中的哪一个发生了?它们在功能上是相同的。没有区别的区别就是没有区别…:-)不要忘记
返回
返回void
,这也会给出
未定义的
。如果您在解释源代码之前有权访问源代码,您可以将最终的
}
替换为
返回someConst其中
someConst
是用户不太可能返回的内容,然后从包装器返回
undefined
。@T.J.Crowder这确实是一个非常独特的用例,它是游戏的一部分,其中涉及到编码-根据使用的代码,会发生不同的事情。我只是在测试一些想法,以前从未遇到过这个问题。但是,我的回答和我预期的一样令人难过。。从JS的视角来看,这是一个微妙的烦恼。看来我必须尝试另一种方法。请您解释一下ainvoker.called()如何从binvoker.called()返回不同的值?我也考虑过这种方法,但我不认为它实际上解决了这个问题。它计算了它被调用的次数。我假设它仍然认为javascript不是多线程的,所以如果call()完成,它将增加调用1,并从a()或b()返回。区别在于ainvoker.called()==1和binvokver.called()==0。但是我可能遗漏了一些东西……@rene建议
返回actualFunc()
to
returnactualfunc.apply(这是参数)
也许你是故意选择将其命名为
call
,但这似乎你忘记了
invokerinstance。call
应该有不同的含义。+1谢谢你的回答,非常正确,但我真的希望在这一层面上避免任何事情。。如果js有某种形式的释放能力或定义默认返回值的方法就好了。+1谢谢。是的,我开始走这条路,但后来开始意识到会涉及到什么,基本上以几乎重新解析所涉及的代码结束:我喜欢这样只是因为它的疯狂!