我被告知不要使用。。。在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]);

其他回答

正在使用。。。虽然我可以猜到为什么有人告诉你:

1.)已经有一个更高阶的函数或方法用于数组,但具有更多的功能和更精简的语法,称为“forEach”:array.protocol.forEach(函数(元素、索引、数组){});

2.)数组总是有长度的,但对于。。。in和forEach不会对任何“undefined”值执行函数,只对定义了值的索引执行函数。因此,如果只分配一个值,这些循环将只执行一次函数,但由于数组是枚举的,因此它的长度将始终达到具有定义值的最高索引,但在使用这些循环时,该长度可能会被忽略。

3.)循环的标准将执行函数的次数与您在参数中定义的次数相同,并且由于数组是编号的,因此定义您希望执行函数的数量更有意义。与其他循环不同,for循环可以为数组中的每个索引执行函数,无论是否定义了值。

本质上,您可以使用任何循环,但您应该记住它们是如何工作的。了解不同循环重复的条件及其各自的功能,并认识到它们或多或少适合不同的场景。

此外,使用forEach方法可能比使用for。。。一般来说,在循环中,因为它更容易编写并且具有更多的功能,所以您可能希望养成只使用此方法和标准的习惯,而不是使用您的调用。

请参见下面的内容,前两个循环只执行一次console.log语句,而标准for循环执行指定次数的函数,在本例中,array.length=6。

var arr = [];
arr[5] = 'F';

for (var index in arr) {
console.log(index);
console.log(arr[index]);
console.log(arr)
}
// 5
// 'F'
// => (6) [undefined x 5, 6]

arr.forEach(function(element, index, arr) {
console.log(index);
console.log(element);
console.log(arr);
});
// 5
// 'F'
// => Array (6) [undefined x 5, 6]

for (var index = 0; index < arr.length; index++) {
console.log(index);
console.log(arr[index]);
console.log(arr);
};
// 0
// undefined
// => Array (6) [undefined x 5, 6]

// 1
// undefined
// => Array (6) [undefined x 5, 6]

// 2
// undefined
// => Array (6) [undefined x 5, 6]

// 3
// undefined
// => Array (6) [undefined x 5, 6]

// 4
// undefined
// => Array (6) [undefined x 5, 6]

// 5
// 'F'
// => Array (6) [undefined x 5, 6]

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

简短的回答:这不值得。


更长的答案:即使不需要顺序元素顺序和最佳性能,这也不值得。


长篇大论:这不值得。。。

使用for(数组中的var属性)将导致数组作为对象迭代,遍历对象原型链,最终执行速度比基于索引的for循环慢。for(…in…)不能保证按顺序返回对象财产,这可能是意料之中的。使用hasOwnProperty()和!用于筛选对象财产的isNaN()检查是一项额外的开销,导致它的执行速度更慢,并否定了首先使用它的主要原因,即因为它的格式更简洁。

出于这些原因,甚至不存在性能和便利性之间可接受的权衡。除非目的是将数组作为对象处理,并对数组的对象财产执行操作,否则实际上没有任何好处。

此外,由于语义的原因,在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"

除了。。。在所有可枚举财产的循环中(这与“所有数组元素”不同!),请参阅http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf,第12.6.4节(第5版)或13.7.5.15节(第7版):

列举财产的机制和顺序。。。未指定。。。

(强调我的。)

这意味着,如果浏览器愿意,它可以按照插入财产的顺序浏览这些属性。或按数字顺序排列。或者按照词法顺序(其中“30”在“4”之前!请记住,所有对象键——因此,所有数组索引——实际上都是字符串,所以这是完全有意义的)。如果它将对象实现为哈希表,那么它可以按桶遍历它们。或者把其中任何一个加上“向后”。浏览器甚至可以随机迭代,并且符合ECMA-262,只要它访问每个属性一次即可。

实际上,大多数浏览器目前都喜欢以大致相同的顺序进行迭代。但没有什么可以说他们必须这样做。这是特定于实现的,如果发现另一种方式更有效,随时可能会改变。

不管怎样,因为。。。它没有秩序的内涵。如果您关心顺序,请明确它,并使用带索引的正则for循环。