Javascript 函数在返回时变为未定义

Javascript 函数在返回时变为未定义,javascript,function,closures,undefined,Javascript,Function,Closures,Undefined,我有: 将字符串前缀映射到函数的字典(functions) 返回映射到字符串的函数的函数(get()) 一个函数(check()),通过调用get()并使用将其强制转换为布尔值来检查是否存在映射到字符串的函数 当我使用函数中的键调用get()时,我希望check()返回true;但是,它返回false。我在get()中执行字典查找,并在两个函数中打印结果的类型。这是奇怪的部分。仅在get()中,类型为function;在check()中,它是未定义的。显然,当我返回函数时,它会被擦除或是其他

我有:

  • 将字符串前缀映射到函数的字典(
    functions
  • 返回映射到字符串的函数的函数(
    get()
  • 一个函数(
    check()
    ),通过调用
    get()
    并使用
    将其强制转换为布尔值来检查是否存在映射到字符串的函数
当我使用
函数中的键调用
get()
时,我希望
check()
返回
true
;但是,它返回
false
。我在
get()
中执行字典查找,并在两个函数中打印结果的类型。这是奇怪的部分。仅在
get()
中,类型为
function
;在
check()
中,它是
未定义的
。显然,当我返回函数时,它会被擦除或是其他什么。如何使
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"

在控制台中。

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

这是因为
forEach
return
语句上没有提前中断/短路(它继续下一次迭代,然后
get
函数返回
未定义的
)。您可以重新写入循环以允许断开(例如,使用简单的
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;
    }
}