我被告知不要使用。。。在JavaScript中使用数组。为什么不呢?


当前回答

一个重要的方面是。。。in-only迭代包含在对象中的财产,该对象的可枚举属性属性设置为true。因此,如果尝试使用for对对象进行迭代。。。然后,如果任意财产的可枚举属性为false,则可能会丢失这些属性。很有可能更改普通Array对象的可枚举属性属性,以便不枚举某些元素。虽然一般来说,属性属性倾向于应用于对象中的函数财产。

可以通过以下方式检查财产的可枚举属性属性的值:

myobject.propertyIsEnumerable('myproperty')

或获取所有四个属性属性:

Object.getOwnPropertyDescriptor(myobject,'myproperty')

这是ECMAScript 5中提供的一个特性——在早期版本中,无法更改可枚举属性属性的值(它总是设置为true)。

其他回答

的问题。。。在…-只有当程序员不真正理解语言时,这才成为问题;它实际上不是一个bug或任何东西,而是它迭代对象的所有成员(好吧,所有可枚举成员,但这只是一个细节)。当您只想迭代数组的索引财产时,确保语义一致的唯一方法是使用整数索引(即for(vari=0;i<array.length;++i)样式循环)。

任何对象都可以有与之关联的任意财产。特别是将附加财产加载到数组实例上并没有什么可怕的。如果代码只想看到索引的类似数组的财产,则必须坚持使用整数索引。完全了解用于…的代码。。。在does和really需要查看所有财产,那么这也没关系。

对于在处理JavaScript中的对象时,in是有用的,但对Array来说不是,但我们仍然不能说这是错误的方法,但不建议这样做,请看下面的示例,使用for。。。循环中:

let txt = "";
const person = {fname:"Alireza", lname:"Dezfoolian", age:35}; 
for (const x in person) {
    txt += person[x] + " ";
}
console.log(txt); //Alireza Dezfoolian 35 

好了,让我们现在使用Array:

let txt = "";
const person = ["Alireza", "Dezfoolian", 35]; 
for (const x in person) {
   txt += person[x] + " ";
}
console.log(txt); //Alireza Dezfoolian 35 

正如你看到的结果一样。。。

但让我们尝试一下,让我们为Array原型。。。

Array.prototype.someoneelse = "someoneelse";

现在我们创建一个新的Array();

let txt = "";
const arr = new Array();
arr[0] = 'Alireza';
arr[1] = 'Dezfoolian';
arr[2] = 35;
for(x in arr) {
 txt += arr[x] + " ";
}
console.log(txt); //Alireza Dezfoolian 35 someoneelse

你看到别人了!!!。。。在本例中,我们实际上循环通过新的Array对象!

这就是为什么我们需要使用。。小心,但情况并非总是这样。。。

因为。。。in通过持有数组的对象枚举,而不是数组本身。如果我向数组原型链中添加了一个函数,那么它也将包含在内。即。

Array.prototype.myOwnFunction = function() { alert(this); }
a = new Array();
a[0] = 'foo';
a[1] = 'bar';
for(x in a){
 document.write(x + ' = ' + a[x]);
}

这将写入:

0 = foo
1 = bar
myOwnFunction = function() { alert(this); }

而且,由于您永远无法确定不会向原型链中添加任何内容,因此只需使用for循环来枚举数组:

for(i=0,x=a.length;i<x;i++){
 document.write(i + ' = ' + a[i]);
}

这将写入:

0 = foo
1 = bar

因为如果你不小心的话,它会迭代属于原型链上对象的财产。

您可以使用。。在中,只需确保使用hasOwnProperty检查每个属性。

除了其他答案中给出的原因外,如果需要计算计数器变量,您可能不想使用“for…In”结构,因为循环会迭代对象财产的名称,因此该变量是一个字符串。

例如

for (var i=0; i<a.length; i++) {
    document.write(i + ', ' + typeof i + ', ' + i+1);
}

将写入

0, number, 1
1, number, 2
...

鉴于

for (var ii in a) {
    document.write(i + ', ' + typeof i + ', ' + i+1);
}

将写入

0, string, 01
1, string, 11
...

当然,这可以通过包括

ii = parseInt(ii);

但第一种结构更直接。