返回时函数变为未定义

Function becomes undefined when returned

我有:

当我使用 functions 中的键调用 get() 时,我希望 check() returns true;然而,它 returns false。我在 get() 中执行字典查找并在两个函数中打印结果的类型。这是奇怪的部分。只有get()中的类型是function;在 check() 中,它是 undefined。显然,当我 return 它时,该功能会被删除或发生其他事情。如何使 check() 准确?

这是我的简化代码:

var someObject = {
    functions: {
        "a": function () { return 0; },
        "b": function () { return 1; }
    },
    get: ( function ( someVariable ) {
        Object.keys( this.functions ).forEach( ( function ( functionKey ) {
            if ( someVariable.startsWith( functionKey ) ) {
                console.log( typeof this.functions[ functionKey ] );
                return this.functions[ functionKey];
            }
        } ).bind( this ) );
    } ),
    check: function ( stringToCheck ) {
        var returnedFunction = this.get( stringToCheck );
        console.log( typeof returnedFunction );
        return !!returnedFunction;
    }
}

$( document ).ready( function () {
    someObject.check( "a" );
} );

运行 此代码生成此:

"function"
"undefined"

在控制台中。

那是因为您 return 从 forEach 回调中调用该函数。它无处可去。

修复可以像 Jack 建议的那样工作,但代码代码要简化:

get: function ( someVariable ) {
        var func;
        Object.keys( this.functions ).some(function ( functionKey ) {
            if ( someVariable.startsWith( functionKey ) ) {
                console.log( typeof this.functions[ functionKey ] );
                func = this.functions[ functionKey];
                return true;
            }
        }, this );
        return func;
    }
  • 您不需要用括号包裹函数
  • 不需要绑定,forEach & some(我用的那个)接受一个thisArg参数。
  • 如果您使用 some,一旦回调 return 为真,迭代就会停止。这在有很多键的情况下效率更高,并且也更准确地匹配您的原始代码试图做的事情。在 Jack 的版本中,如果 ['a', 'b', 'aa'] 处的键,您将迭代所有 3 个和 return 'aa',而您的代码(和我的)在第一个 'a' 之后停止。

这是因为 forEach 没有打破 return 语句上的 early/short 电路(它继续下一次迭代,然后是 get 函数 returns undefined)。您可以重新编写循环以允许中断(例如,使用简单的 for-loop),或者您可以 return 循环后的值,例如:

var someObject = {
    functions: {
        "a": function () { return 0; },
        "b": function () { return 1; }
    },
    get: ( function ( someVariable ) {
        var func;
        Object.keys( this.functions ).forEach( ( function ( functionKey ) {
            if ( someVariable.startsWith( functionKey ) ) {
                console.log( typeof this.functions[ functionKey ] );
                func = this.functions[ functionKey];
            }
        } ).bind( this ) );
        return func;
    } ),
    check: function ( stringToCheck ) {
        var returnedFunction = this.get( stringToCheck );
        console.log( typeof returnedFunction );
        return !!returnedFunction;
    }
}