我不明白javascript中的这个array.reverse()
Posted
技术标签:
【中文标题】我不明白javascript中的这个array.reverse()【英文标题】:I don't understand this array.reverse() in javascript 【发布时间】:2015-05-29 23:35:55 【问题描述】:下面的代码会向控制台输出什么,为什么?
var arr1 = "john".split('');
var arr2 = arr1.reverse();
var arr3 = "jones".split('');
arr2.push(arr3);
console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(-1));
console.log("array 2: length=" + arr2.length + " last=" + arr2.slice(-1));
输出将是: “数组 1:长度=5 最后=j,o,n,e,s” "数组 2: length=5 last=j,o,n,e,s"
这是与此问题一起发布的答案。但是,我不明白这是遵循什么 javascript 原则或规则?
“reverse() 方法返回对数组本身的引用(即在本例中为 arr1)。因此,arr2 只是对 arr1 的引用(而不是副本)。因此,当任何对 arr2 完成(即,当我们调用 arr2.push(arr3); 时),arr1 也会受到影响,因为 arr1 和 arr2 只是对同一个对象的引用。"
【问题讨论】:
表示reverse
是就地算法。
var x = [1,2,3]; x.reverse(); console.log(x); // => [3,2,1]
请注意,您不必将x.reverse()
分配给另一个变量;相反,该操作是在阵列上执行的。相反,.map
之类的操作不会像 x.map(function (d) return d * 2; ); console.log(x); // => [3,2,1]
那样工作,因为它们不能根据引用工作
很难改进这个答案。 Array.prototype.reverse 反转它所调用的数组,然后返回对该数组的引用。所以在 b 是一个数组的地方,var a = b.reverse()
的结果是 b 被反转并且 a 被分配了一个对它的引用,所以两者a 和 b 引用同一个数组。
【参考方案1】:
这段代码中要注意的一点是行号。 2
var arr2 = arr1.reverse();
此代码表示将存储在内存中的数组反转[arr1 指向的] 并让 arr2 也指向同一个数组。
因此,您最终对 arr1 所引用的数组多了一个引用[arr2]。
然后你通过这个新的引用 arr2 更新同一个数组。
arr2.push(arr3);
因此,您始终将一个数组存储在内存中,并且两个引用[arr1 和 arr2] 指向相同的数组。您可以通过任何引用更新存储在该内存中的值,并且所有引用都将反映更改,因为它们指向相同的内存。
【讨论】:
【参考方案2】:我认为原因是将 arr1.reverse() 分配给 arr2 就像将其绑定到它。您仍然使用相同的数组,而不是创建 arr1 的新实例。
所以
arr2.push(arr3);
等价于
arr1.reverse().push(arr3)
当你这样看时,它自然会影响 arr1
我可能是错的,但这就是我认为正在发生的事情
【讨论】:
【参考方案3】:让我们逐行分解:
var arr1 = "john".split('');
arr1 现在指向数组 ['j','o','h','n']。
var arr2 = arr1.reverse();
arr1 和 arr2 现在指向同一个数组,即 ['n','h','o','j']。
var arr3 = "jones".split('');
arr3 现在指向数组 ['j','o','n','e','s']。
arr2.push(arr3);
arr2 和 arr1 现在都指向数组 ['n','h','o','j', [ 'j','o','n','e','s'] ]。请注意,arr3 的元素不会附加到 arr1 和 arr2 指向的数组中。而是将整个数组作为单个元素添加。
console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(-1));
记录 arr1 的长度,即 5('n'、'h'、'o'、'j' 和第二个数组)。 arr1.slice(-1) 获取 arr1 数组的最后一个元素,即包含 'j','o','n','e','s' 的数组。最后一行复制了这一点,但使用了 arr2,它只是对与 arr1 相同的数组的另一个引用。
【讨论】:
【参考方案4】:执行以下操作:
var arr1 = "john".split(''); //splits into j, o, h, n
var arr2 = arr1.reverse(); // reverses the array to n, h, o, j
var arr3 = "jones".split(''); // splits into j, o, n, e, s
arr2.push(arr3); // adds arr3 to the end of arr2
console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(-1));
console.log("array 2: length=" + arr2.length + " last=" + arr2.slice(-1));
【讨论】:
不喜欢纯代码的答案,您需要用清晰、简单的语言解释您的答案。 cmets 不会那样做。 这并不能解释为什么arr3
会同时添加到arr1
和arr2
。
每行旁边的cmets解释清楚。以上是关于我不明白javascript中的这个array.reverse()的主要内容,如果未能解决你的问题,请参考以下文章