Javascript underline.js every()带有未定义的
我编写了如下代码:Javascript underline.js every()带有未定义的,javascript,underscore.js,Javascript,Underscore.js,我编写了如下代码: var a = new Array(10); // should be [undefined * 10] var b = _.every(a, function(m){ if(_.isUndefined(m)){ return false; } return true; }); 我希望b是“假”,但它返回“真”。 为什么它返回“真” 然后,我改为: var c = [undefined, undefined]; var d = _.
var a = new Array(10); // should be [undefined * 10]
var b = _.every(a, function(m){
if(_.isUndefined(m)){
return false;
}
return true;
});
我希望b是“假”,但它返回“真”。
为什么它返回“真”
然后,我改为:
var c = [undefined, undefined];
var d = _.every(c, function(m){
if(_.isUndefined(m)){
return false;
}
return true;
});
它在d中返回'false'
为什么它们不同
您可以在中测试这一点。使用数组构造函数和初始大小初始化数组与使用显式列表的
未定义的
项初始化数组之间有细微的区别。前者(数组构造函数)不创建与索引对应的属性,而显式初始化则创建
我怀疑下划线正在使用本机的.forEach()
,如果可能的话,它不会调用未初始化索引的回调。因此,在第一个测试中,根本不会调用对.each()
的回调
编辑-数组构造函数执行的操作或多或少与以下操作相同:
var a = []; a.length = 10;
当您通过这样增加数组的长度来扩展数组时,新的隐式索引位置不会初始化。这是财产不存在和财产没有价值之间的基本区别。在这两种情况下,取消对属性的引用都会导致未定义。因此:
var o = {};
if (o.something == undefined) // this will be true
然后:
var o = { something: undefined };
if (o.something == undefined) // also true
区分这两种情况的一种方法是
中的:
if ('something' in o) // only true in the second case
使用数组构造函数和初始大小初始化数组与使用未定义项的显式列表初始化数组之间存在细微差别。前者(数组构造函数)不创建与索引对应的属性,而显式初始化则创建
我怀疑下划线正在使用本机的.forEach()
,如果可能的话,它不会调用未初始化索引的回调。因此,在第一个测试中,根本不会调用对.each()
的回调
编辑-数组构造函数执行的操作或多或少与以下操作相同:
var a = []; a.length = 10;
当您通过这样增加数组的长度来扩展数组时,新的隐式索引位置不会初始化。这是财产不存在和财产没有价值之间的基本区别。在这两种情况下,取消对属性的引用都会导致未定义。因此:
var o = {};
if (o.something == undefined) // this will be true
然后:
var o = { something: undefined };
if (o.something == undefined) // also true
区分这两种情况的一种方法是
中的:
if ('something' in o) // only true in the second case
当您使用类初始值设定项创建数组时,您正在创建一个具有10个可用内存空间的数组,但它们都尚未初始化。所以你没有在任何事情上循环
现在查看每个
的源代码:
_.every = _.all = function(obj, iterator, context) {
iterator || (iterator = _.identity);
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
});
return !!result;
};
结果
设置为真
,由于每个
不进行迭代,因此返回结果。这就是您返回true
的原因
如果在您的小提琴中尝试在处理程序中添加console.log(m)
,您将在控制台中看不到任何日志,因为每个迭代0次。当您使用类初始值设定项创建数组时,您正在创建一个具有10个可用内存空间的数组,但它们都尚未初始化。所以你没有在任何事情上循环
现在查看每个
的源代码:
_.every = _.all = function(obj, iterator, context) {
iterator || (iterator = _.identity);
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
});
return !!result;
};
结果
设置为真
,由于每个
不进行迭代,因此返回结果。这就是您返回true
的原因
如果您在小提琴中尝试在处理程序中添加一个console.log(m)
,您将不会在控制台中看到任何日志,因为每个重复0次。我使用console.log(a)
,它会打印出[undefined x 10]
。和console.log(a[1])
,打印出未定义的。这让我很困惑。如果我可以使用a[1]
获取某些内容,为什么我不能对其进行迭代?我使用console.log(a)
,它会打印出[undefined x 10]
。和console.log(a[1])
,打印出未定义的。这让我很困惑。如果我可以使用a[1]
来获取某些内容,为什么我不能迭代它?