当返回时函数变为未定义

3
我有:
  • 一个将字符串前缀映射到函数的字典(functions
  • 一个函数(get()),它返回映射到字符串的函数
  • 一个函数(check()),通过调用 get() 并使用 !! 将其转换为布尔值来检查是否存在映射到字符串的函数。
当我使用 functions 中的键调用 get() 时,我希望 check() 返回 true;但是,它返回了 false。我在 get() 中执行字典查找并打印两个函数中结果的类型。这里有奇怪的部分。类型仅在 get() 中为 function;在 check() 中为 undefined。显然,当我返回它时,该函数被清除或某些东西。如何使 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"

在控制台中。

2个回答

2

这是因为forEachreturn语句上不会提前结束/短路(它会继续进行下一次迭代,然后get函数返回undefined)。您可以重新编写循环以允许中断(例如,使用简单的for-loop),或者您可以在循环后返回值,例如:

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

1
那是因为你在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;
    }
  • 您不需要用括号包裹函数
  • 您不需要绑定,forEachsome(我使用的那个)接受一个thisArg参数。
  • 如果您使用some,则迭代会在回调返回true时立即停止。这在有许多键的情况下更有效,并且更准确地匹配了您原始代码尝试执行的操作。在Jack的版本中,如果键是['a','b','aa'],则会迭代所有3个,然后返回“aa”,而您的代码(以及我的代码)会在第一个“a”之后停止。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,