我在ideone中尝试以下代码:
var a = [];
a[0] = 0;
a[5] = 5;
a[6] = undefined;
print("contents before popping:");
for(var e in a) print("\ta[", e, "] =", a[e]);
print("a.length =", a.length);
for (var i = 0; i < a.length; i++)
print("\ta.hasOwnProperty(", i, ") =", a.hasOwnProperty(i));
print("popping -->", a.pop());
print("popping -->", a.pop());
print("contents after popping:");
for(var e in a) print("\ta[", e, "] =", a[e]);
print("a.length =", a.length);
for (var i = 0; i < a.length; i++)
print("\ta.hasOwnProperty(", i, ") =", a.hasOwnProperty(i));
输出如下:
contents before popping:
a[ 0 ] = 0
a[ 5 ] = 5
a[ 6 ] = undefined
a.length = 7
a.hasOwnProperty( 0 ) = true
a.hasOwnProperty( 1 ) = false
a.hasOwnProperty( 2 ) = false
a.hasOwnProperty( 3 ) = false
a.hasOwnProperty( 4 ) = false
a.hasOwnProperty( 5 ) = true
a.hasOwnProperty( 6 ) = true
popping --> undefined
popping --> 5
contents after popping:
a[ 0 ] = 0
a.length = 5
a.hasOwnProperty( 0 ) = true
a.hasOwnProperty( 1 ) = false
a.hasOwnProperty( 2 ) = false
a.hasOwnProperty( 3 ) = false
a.hasOwnProperty( 4 ) = false
在我的JavaScript书(好吧,Crockford's)中,我读到数组的长度被计算为所有属性的最大数值。那么,为什么它的最大数值属性为0时长度为5?谢谢!
答案 0 :(得分:6)
关于Javascript的一个好处是它的语义在形式上正如标准中定义的那样明确无误。具体来说,section 15.4表示:
length属性的值在数值上大于名称为数组索引的每个属性的名称;无论何时创建或更改Array对象的属性,都会根据需要调整其他属性以保持此不变量。
换句话说,每次更改数组时,其length
都会被调整,但是,它只能保证大于max(indexes)
,并且不一定等于max(indexes)+1
。例如,pop method总是删除length-1
'元素并将length
减1,无论数组实际包含多少元素。
另请注意,大多数数组方法都是通用的,并且不会“专门”了解有关数组的任何信息。它们可以操纵任意对象,如果这样的对象碰巧有一个名为length
的属性,它将根据上述规则进行调整。考虑:
foo = {
length: 100,
99: 'hi'
}
alert([].pop.apply(foo)) // hi
alert(foo.length) // 99
alert([].pop.apply(foo)) // undefined
alert(foo.length) // 98
也就是说,在您的问题的上下文中,如何准确表示数组 - pop
并且朋友不使用此信息。
答案 1 :(得分:1)
“问题”是5
的作业。
你做的第二个, Javascript数组充满了使用undefined
值初始化的插槽。
所以打电话
a[5] = 5;
原因
[0, undefined, undefined, undefined, undefined, 5]
然后你也创建a[6]
并用undefined
初始化它,我们得到
[0, undefined, undefined, undefined, undefined, 5, undefined]
.length
的 7
。
现在我们调用 double .pop()
(喜欢doublepop这个词)我们得到了
[0, undefined, undefined, undefined, undefined]
5 的 .length
实际上,正如评论中指出的那样,这似乎仍然是非常奇怪的行为。初始化任何索引时,之前的插槽实际上并没有被任何指定。它创建了一个稀疏数组。但话又说回来,如果我们删除最后两个条目,则只剩下一个值(0
),后跟undefined
个值(某种程度变为 real 值,可能是因为我们手动分配了6
。
我想我们需要一个实现大师:)
答案 2 :(得分:1)
“数组的长度计算为所有数值的最大值 属性“
这对于阵列的所有用途都不准确。如果为数组中的索引指定值,则会以这种方式工作,但如果您专门设置length
或使用pop
之类的方法则不行。
示例:
var a = [];
a.length = 5;
console.log("length =", a.length);
for (var i = 0; i < a.length; i++)
console.log("a.hasOwnProperty(", i, ") =", a.hasOwnProperty(i));
输出:
length = 5
a.hasOwnProperty(0) = false
a.hasOwnProperty(1) = false
a.hasOwnProperty(2) = false
a.hasOwnProperty(3) = false
a.hasOwnProperty(4) = false
现在你有一个没有任何项目的数组,但长度为5。
答案 3 :(得分:0)
问题实际上与您没有使用顺序索引而不是使用pop函数这一事实有关。您会注意到,在第一个长度打印时,数组的长度为7,但数组中只有3个项目。这与length返回最大索引/属性(+1)的事实有关,因为其余的值被设置为未定义的值。
你真的必须使用非顺序索引吗?如果是这样,您可能想尝试使用:
var counter = 0;
for (var i in a) {
counter++;
print("Property: "+i);
}
print("Total items: "+counter);
但这远不是最佳的,性能明智。