简体   繁体   English

在JavaScript中循环数组时的奇怪行为

[英]odd behavior while looping over an array in JavaScript

I'm reading through Eloquent Javascript and facing one of the exercises, I found a rather odd behavior. 我正在阅读Eloquent Javascript并面对其中一个练习,我发现了一个相当奇怪的行为。 (at least for me) (至少对我来说)

the exercise asks to create a function in order to reverse an array. 练习要求创建一个函数以反转数组。 I thought I could loop over the array and each time pop one item from the original array and push it into a temporary array that is going to finally be returned. 我以为我可以遍历数组,每次从原始数组中弹出一个项目并将其推送到最终将被返回的临时数组中。 but as I'm looping over the array either with a for-of loop or typical sequential loop, last item is not transferred. 但是当我使用for-of循环或典型的顺序循环遍历数组时,最后一项不会被传输。

can someone tell me what happens exactly? 谁能告诉我究竟发生了什么?

const reverseArray = function(array) {
let rev = [];
for (let x = 0; x <= array.length; x++) {

    rev.push(array.pop());
    console.log(rev, array)
}
return rev;
};


console.log(reverseArray(["A", "B", "C"]));

output: 输出:

["C"] ["A", "B"]
["C", "B"] ["A"]
["C", "B"]

When the pop() applies on array it decreases the length of the array so when the loop runs it finds one item less than the previous array length. pop()适用于array它降低了的长度array所以当循环运行它找到比以前的阵列长度少一个项目。 Thus, what you can do is simply assign the length of the array in a variable and use that in the comparison of the for loop: 因此,您可以做的只是在变量中分配array的长度,并在for循环的比较中使用它:

 let rev = []; const reverseArray = function(array) { var length = array.length; for (let x = 0; x < length; x++) { rev.push(array.pop()); } return rev; }; console.log(reverseArray(["A", "B", "C"])); 

As the pop() method remove the pop'ed item from the array, use a while loop instead of for pop()方法从数组中删除pop'ed项时,使用while循环而不是for

 let rev = []; const reverseArray = function(array) { while (array.length > 0) { // or just "(array.length)" rev.push(array.pop()); } return rev; } console.log(reverseArray(["A", "B", "C"])); 

With closure you can save yourself an extra global variable 通过closure您可以节省额外的全局变量

 const reverseArray = function(array) { return (function(a_in,a_out) { while (a_in.length > 0) { // or just "(a_in.length)" a_out.push(a_in.pop()); } return a_out; })(array,[]); } console.log(reverseArray(["A", "B", "C"])); 

Or if the Array.reverse() method is allowed 或者,如果允许Array.reverse()方法

 const reverseArray = function(array) { return array.reverse(); } console.log(reverseArray(["A", "B", "C"])); 

The pop() method removes the last element of an array, and returns that element. pop()方法删除数组的最后一个元素,并返回该元素。 It changes the length of an array. 它改变了数组的长度。

 const popArray = function(array) { for (let x = 0; x <= array.length; x++) { console.log("value of x :", x); console.log("array.length :", array.length); array.pop(); console.log("array after", x + 1, "pop :", array); } }; popArray(["A", "B", "C"]); 

In the above demo we can see that everytime pop() happens on an array. 在上面的demo我们可以看到每次pop()都发生在一个数组上。 array.length will decrease and value of x will be increase. array.length将减少, x值将增加。 Hence, At certain point of time (after 2nd iteration) value of x will be greater then the length of an array. 因此,在某个时间点(在第二次迭代之后), x值将greater数组的长度。

Use Array.from() method : 使用Array.from()方法:

 let rev = []; const reverseArray = function(array) { var destinationArray = Array.from(array); for (var i in Array.from(array)) { rev.push(array.pop()); console.log(rev, array); } }; reverseArray(["A", "B", "C"]); 

Try using while loop instead of for loop 尝试使用while循环而不是for循环

const reverseArray = function(array){                                       
let rev = [];                                                             
while (array.length>0)                                                        
{                           
rev.push(array.pop());                                                       
}                                                  
return rev;                                                                  
};                                             
console.log(reverseArray(["A", "B", "C"]));

I put two versions for you. 我为你准备了两个版本。 reverse will reverse the array without modifying the original array. reverse将反转数组而不修改原始数组。 reverseModify will do the same, but emptying the original array. reverseModify也会这样做,但是清空原始数组。

Choose the version that suits you better 选择最适合您的版本

 const arr = [1, 2, 3, 4]; function reverse(array) { let result = []; for (let i = array.length - 1; i >= 0; i--) { result.push(array[i]); } return result; } function reverseModify(array) { let result = []; while (array.length) { result.push(array.pop()); } return result; } console.log(reverse(arr), arr); console.log(reverseModify(arr), arr); 

The problem is divides into two independent operations. 问题分为两个独立的操作。

  1. iterate all elements, usually take the length and perform a loop 迭代所有元素,通常取长度并执行循环

  2. pop a value and push that value. This is the mechanism to take the last pop一个值并push that value. This is the mechanism to take the last push that value. This is the mechanism to take the last item and push it to the end of the new array. push that value. This is the mechanism to take the last一项并将其推送到新数组末尾的机制。

The part for iterating needs only the actual length and a count down (by pop ) to zero and then exit the loop. 迭代部分只需要实际长度和倒计时(通过pop )为零,然后退出循环。

For a count up, you need two vvariables, one for the counter and one for the end or length of the array, which is a static value, take from the given array, which is later mutating. 对于计数,你需要两个vvariables,一个用于计数器,一个用于数组的结束或长度,这是一个静态值,取自给定的数组,后来发生变异。

 function reverseArray(array) { var rev = []; while (array.length) { rev.push(array.pop()); } return rev; } console.log(reverseArray(["A", "B", "C"])); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM