数组 return `true` 中的未定义条目在使用 `every` 将它们解析为布尔值后
Undefined entries in an array return `true` after parsing them as boolean with `every`
为了跟踪 3 个布尔值,我决定使用一个简单的数组:
var processingDone = Array(3);
然后,我将布尔值设置为正确的索引(伪代码):
function stepTwoDone(){
processingDone[1] = true;
}
我想出了一个简单的方法来检查是否所有的布尔值都为真,就是使用 every
,像这样:
if(processingDone.every(Boolean)){
// Do stuff
}
现在,由于某种原因,如果不是所有的布尔值都被设置,但是 设置的所有布尔值都是 true
,every
returns true
:
alert('Array(3): ' + Array(3).every(Boolean) + '\n' + // true
'[,,]: ' + [,,].every(Boolean) + '\n' + // true
'[true,,true]: ' + [true,,true].every(Boolean) + '\n' + // true
'[,false,]: ' + [,false,].every(Boolean) + '\n' + // false
'All true: ' + [true,true,true].every(Boolean) + '\n' + // true
'All false: ' + [false,false,false].every(Boolean)); // false
那么,这是怎么回事?
为什么数组中的未定义值在传递给 Boolean
构造函数时看起来等于真值?只需调用 Boolean()
不带参数 returns false
,如预期...
当然,简单的解决方案是首先将值设置为虚假值:
var processingDone = [false, false, false];
MDN forEach
forEach executes the provided callback once for each element present
in the array in ascending order. It is not invoked for indexes that
have been deleted or elided. However, it is executed for elements that
are present and have the value undefined.
我强烈怀疑 every
也是这样循环的,尽管我正在搜索规范。
因此,当 [true,,true]
调用 every
时,只有 [true,true]
(比方说)被传递,因为第二个元素被忽略。但是请考虑以下
[true,undefined,true].every(Boolean) // false
上面的returnsfalse
作为它实际上包含值undefined
,而不仅仅是undefined
的结果这就是当我们尝试访问索引尚未设置的数组元素时得到的结果。
在我们的例子中,[true,,true]
在 0 和 2 索引中有值,但在 1
中没有
总结:
布尔值(或指定的回调)仅针对存在的实际值调用,而不针对导致 falsey 值 (undefined
) 的值调用,因为它们不'首先存在。
ECMAScript Language Specification - ECMA-262 Edition 5.1 also suggests the same
这就是 array.every 的工作原理:
为每个已赋值的数组元素调用回调,它不会为已删除或从未赋值的索引(例如您的 Array(3) )调用
如果回调 return 为假值,它将 return 为假。因为您没有分配值,所以 Boolean 永远不会被调用。
试一试
[false,false,false].every(function(value) {
console.info(arguments);
return true;
});
对比(无控制台输出)
Array(3).every(function(value) {
console.info(arguments);
return true;
});
为了跟踪 3 个布尔值,我决定使用一个简单的数组:
var processingDone = Array(3);
然后,我将布尔值设置为正确的索引(伪代码):
function stepTwoDone(){
processingDone[1] = true;
}
我想出了一个简单的方法来检查是否所有的布尔值都为真,就是使用 every
,像这样:
if(processingDone.every(Boolean)){
// Do stuff
}
现在,由于某种原因,如果不是所有的布尔值都被设置,但是 设置的所有布尔值都是 true
,every
returns true
:
alert('Array(3): ' + Array(3).every(Boolean) + '\n' + // true
'[,,]: ' + [,,].every(Boolean) + '\n' + // true
'[true,,true]: ' + [true,,true].every(Boolean) + '\n' + // true
'[,false,]: ' + [,false,].every(Boolean) + '\n' + // false
'All true: ' + [true,true,true].every(Boolean) + '\n' + // true
'All false: ' + [false,false,false].every(Boolean)); // false
那么,这是怎么回事?
为什么数组中的未定义值在传递给 Boolean
构造函数时看起来等于真值?只需调用 Boolean()
不带参数 returns false
,如预期...
当然,简单的解决方案是首先将值设置为虚假值:
var processingDone = [false, false, false];
MDN forEach
forEach executes the provided callback once for each element present in the array in ascending order. It is not invoked for indexes that have been deleted or elided. However, it is executed for elements that are present and have the value undefined.
我强烈怀疑 every
也是这样循环的,尽管我正在搜索规范。
因此,当 [true,,true]
调用 every
时,只有 [true,true]
(比方说)被传递,因为第二个元素被忽略。但是请考虑以下
[true,undefined,true].every(Boolean) // false
上面的returnsfalse
作为它实际上包含值undefined
,而不仅仅是undefined
的结果这就是当我们尝试访问索引尚未设置的数组元素时得到的结果。
在我们的例子中,[true,,true]
在 0 和 2 索引中有值,但在 1
总结:
布尔值(或指定的回调)仅针对存在的实际值调用,而不针对导致 falsey 值 (undefined
) 的值调用,因为它们不'首先存在。
ECMAScript Language Specification - ECMA-262 Edition 5.1 also suggests the same
这就是 array.every 的工作原理:
为每个已赋值的数组元素调用回调,它不会为已删除或从未赋值的索引(例如您的 Array(3) )调用
如果回调 return 为假值,它将 return 为假。因为您没有分配值,所以 Boolean 永远不会被调用。
试一试
[false,false,false].every(function(value) {
console.info(arguments);
return true;
});
对比(无控制台输出)
Array(3).every(function(value) {
console.info(arguments);
return true;
});