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


当前回答

因为。。。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

其他回答

对于在处理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对象!

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

原因是一个构造:

变量a=[];//创建新的空数组。a[5]=5;//调整数组大小的完全合法的JavaScript。对于(var i=0;i<a.length;i++){//按照每个人的预期,在从0到5的数字索引上重复。控制台日志(a[i]);}/*将显示:未定义未定义未定义未定义未定义5.*/

有时可能完全不同:

变量a=[];a[5]=5;for(a中的var x){//仅显示显式设置的索引“5”,并忽略0-4console.log(x);}/*将显示:5.*/

还要考虑JavaScript库可能会这样做,这会影响您创建的任何数组:

//在JavaScript库的深处。。。Array.prototype.foo=1;//现在你不知道下面的代码会做什么。变量a=[1,2,3,4,5];for(a中的var x){//现在foo是每个数组的一部分//将在此处显示为“x”值。console.log(x);}/*将显示:01.2.3.4.食品*/

因为它通过对象字段而不是索引枚举。你可以用索引“length”获得值,我怀疑你是否想要这个。

您应该只在属性列表上使用for(var x in y),而不是在对象上(如上所述)。

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

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

myobject.propertyIsEnumerable('myproperty')

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

Object.getOwnPropertyDescriptor(myobject,'myproperty')

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