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


当前回答

我认为我没有什么要补充的,比如Triptych的答案或CMS关于为什么使用for。。。在某些情况下应避免。

然而,我想补充一点,在现代浏览器中,有一种替代。。。在这种情况下。。。无法使用中的。另一种选择是。。。第页,共页:

for (var item of items) {
    console.log(item);
}

注:

遗憾的是,没有版本的Internet Explorer支持。。。(Edge 12+确实如此),因此您必须等待一段时间,直到可以在客户端生产代码中使用它。然而,在服务器端JS代码中使用它应该是安全的(如果您使用Node.JS)。

其他回答

截至2016年(ES6),我们可能会使用for…for数组迭代,正如John Slegers已经注意到的那样。

我只想添加一个简单的演示代码,以使事情更清楚:

Array.prototype.foo = 1;
var arr = [];
arr[5] = "xyz";

console.log("for...of:");
var count = 0;
for (var item of arr) {
    console.log(count + ":", item);
    count++;
    }

console.log("for...in:");
count = 0;
for (var item in arr) {
    console.log(count + ":", item);
    count++;
    }

控制台显示:

for...of:

0: undefined
1: undefined
2: undefined
3: undefined
4: undefined
5: xyz

for...in:

0: 5
1: foo

换句话说:

对于的计数从0到5,并且还忽略Array.prototype.foo。它显示数组值。对于中只列出了5个,忽略了未定义的数组索引,但添加了foo。它显示数组属性名称。

for in循环在遍历数组时将索引转换为字符串。例如,在下面的代码中,在用i+1初始化j的第二个循环中,i是索引,但在字符串(“0”、“1”等)中,js中的number+string是字符串。如果js遇到“0”+1,则返回“01”。

var maxProfit=函数(价格){设maxProfit=0;for(让我输入价格){for(设j=i+1;j<prices.length;j++){console.log(价格[j]-价格[i],“i,j”,i,j,类型i,类型j);如果((prices[j]-prices[i])>maxProfit)maxProfit=(prices[j]-prices[i]);}}return maxProfit;};最大利润([7,1,5,3,6,4]);

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

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

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

myobject.propertyIsEnumerable('myproperty')

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

Object.getOwnPropertyDescriptor(myobject,'myproperty')

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

主要有两个原因:

One

就像其他人所说的那样,您可能会得到不在数组中或从原型继承的密钥。因此,假设库向Array或Object原型添加了一个属性:

Array.prototype.someProperty = true

您可以将其作为每个阵列的一部分:

for(var item in [1,2,3]){
  console.log(item) // will log 1,2,3 but also "someProperty"
}

可以使用hasOwnProperty方法解决此问题:

var ary = [1,2,3];
for(var item in ary){
   if(ary.hasOwnProperty(item)){
      console.log(item) // will log only 1,2,3
   }
}

但这对于使用for in循环迭代任何对象都是正确的。

Two

通常,数组中项目的顺序很重要,但for in循环不一定以正确的顺序迭代,这是因为它将数组视为对象,这是在JS中实现的方式,而不是数组。这看起来是一件小事,但它确实会破坏应用程序,而且很难调试。