我被告知不要使用。。。在JavaScript中使用数组。为什么不呢?
当前回答
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]);
其他回答
简短的回答:这不值得。
更长的答案:即使不需要顺序元素顺序和最佳性能,这也不值得。
长篇大论:这不值得。。。
使用for(数组中的var属性)将导致数组作为对象迭代,遍历对象原型链,最终执行速度比基于索引的for循环慢。for(…in…)不能保证按顺序返回对象财产,这可能是意料之中的。使用hasOwnProperty()和!用于筛选对象财产的isNaN()检查是一项额外的开销,导致它的执行速度更慢,并否定了首先使用它的主要原因,即因为它的格式更简洁。
出于这些原因,甚至不存在性能和便利性之间可接受的权衡。除非目的是将数组作为对象处理,并对数组的对象财产执行操作,否则实际上没有任何好处。
因为如果你不小心的话,它会迭代属于原型链上对象的财产。
您可以使用。。在中,只需确保使用hasOwnProperty检查每个属性。
孤立地说,在数组中使用for没有错。For-in迭代对象的属性名,在“现成”数组的情况下,财产对应于数组索引。(像length、toString等内置属性不包含在迭代中。)
然而,如果您的代码(或您正在使用的框架)将自定义财产添加到数组或数组原型中,那么这些财产将包含在迭代中,这可能不是您想要的。
一些JS框架,如Prototype修改了Array原型。像JQuery这样的其他框架则不然,因此使用JQuery,您可以在中安全地使用。
如果你有疑问,你可能不应该使用。
迭代数组的另一种方法是使用for循环:
for (var ix=0;ix<arr.length;ix++) alert(ix);
然而,这有一个不同的问题。问题是JavaScript数组可能有“洞”。如果您将arr定义为:
var arr = ["hello"];
arr[100] = "goodbye";
然后数组有两个项目,但长度为101。在中使用for将产生两个索引,而for循环将产生101个索引,其中99的值为undefined。
一个重要的方面是。。。in-only迭代包含在对象中的财产,该对象的可枚举属性属性设置为true。因此,如果尝试使用for对对象进行迭代。。。然后,如果任意财产的可枚举属性为false,则可能会丢失这些属性。很有可能更改普通Array对象的可枚举属性属性,以便不枚举某些元素。虽然一般来说,属性属性倾向于应用于对象中的函数财产。
可以通过以下方式检查财产的可枚举属性属性的值:
myobject.propertyIsEnumerable('myproperty')
或获取所有四个属性属性:
Object.getOwnPropertyDescriptor(myobject,'myproperty')
这是ECMAScript 5中提供的一个特性——在早期版本中,无法更改可枚举属性属性的值(它总是设置为true)。
此外,由于语义的原因,在treats数组(即与任何其他JavaScript对象相同)中使用的方法与其他流行语言不一致。
// C#
char[] a = new char[] {'A', 'B', 'C'};
foreach (char x in a) System.Console.Write(x); //Output: "ABC"
// Java
char[] a = {'A', 'B', 'C'};
for (char x : a) System.out.print(x); //Output: "ABC"
// PHP
$a = array('A', 'B', 'C');
foreach ($a as $x) echo $x; //Output: "ABC"
// JavaScript
var a = ['A', 'B', 'C'];
for (var x in a) document.write(x); //Output: "012"