返回时函数变为未定义
Function becomes undefined when returned
我有:
- 字典 (
functions
) 将字符串前缀映射到函数
- 一个函数 (
get()
) return 函数映射到一个字符串
- 一个函数 (
check()
),它通过调用 get()
并将其转换为带有 !!
. 的布尔值来检查是否存在映射到字符串的函数
当我使用 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;
}
}
我有:
- 字典 (
functions
) 将字符串前缀映射到函数 - 一个函数 (
get()
) return 函数映射到一个字符串 - 一个函数 (
check()
),它通过调用get()
并将其转换为带有!!
. 的布尔值来检查是否存在映射到字符串的函数
当我使用 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;
}
}