我被告知不要使用。。。在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循环。
推荐文章
- 我如何使用Jest模拟JavaScript的“窗口”对象?
- 我如何等待一个承诺完成之前返回一个函数的变量?
- 在JavaScript中根据键值查找和删除数组中的对象
- 使嵌套JavaScript对象平放/不平放的最快方法
- 在Bash中模拟do-while循环
- 如何以及为什么'a'['toUpperCase']()在JavaScript工作?
- 有Grunt生成index.html不同的设置
- 文档之间的区别。addEventListener和window。addEventListener?
- 如何检查动态附加的事件监听器是否存在?
- 如何确定一个数组是否包含另一个数组的所有元素
- 如何写setTimeout与参数Coffeescript
- 将JavaScript字符串中的多个空格替换为单个空格
- 加快R中的循环操作
- 给定一个数字数组,返回所有其他数字的乘积的数组(不除法)
- 多维数组如何在内存中格式化?