【问题标题】:Function becomes undefined when returned返回时函数未定义
【发布时间】:2015-07-31 22:28:12
【问题描述】:

我有:

  • 将字符串前缀映射到函数的字典 (functions)
  • 返回映射到字符串的函数的函数 (get())
  • 一个函数 (check()),它通过调用 get() 并使用 !! 将其转换为布尔值来检查是否存在映射到字符串的函数。

当我使用functions 中的键调用get() 时,我希望check() 返回true;但是,它返回false。我在get() 中执行字典查找并在两个函数中打印结果的类型。这是奇怪的部分。类型为function 仅在get();在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"

在控制台中。

【问题讨论】:

    标签: javascript function closures undefined


    【解决方案1】:

    这是因为forEach 不会在return 语句上提前中断/短路(它继续下一次迭代,然后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;
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是因为您从 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,则一旦回调返回true,迭代就会停止。这在有很多键的情况下效率更高,并且更准确地匹配您的原始代码尝试执行的操作。在 Jack 的版本中,如果 ['a', 'b', 'aa'] 所在的键,您将迭代所有 3,并返回 'aa',而您的代码(和我的)在第一个 'a' 之后停止。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-10-22
        • 2019-01-07
        • 2020-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多