如何在JavaScript中交换2D数组中的两个元素? (对我在Chrome中的console.log中看到的内容感到困惑)

问题描述 投票:4回答:2

我想在2D数组中交换两个数组,但JS似乎在我的实际交换发生之前就这样做了。

这是我正在研究的算法,提供了显示点列表的每种可能方法。我已经尝试了几种方法来做到这一点,但关键问题一直在回归,我已经成功地将其简化为代码的平衡:

var points = [[1,2],[10,20],[100,200]];
console.log(points);
var a = points[1][0];
var b = points[1][1];
points[1][0] = points[2][0];
points[1][1] = points[2][1];
points[2][0] = a;
points[2][1] = b;
console.log(points);

我知道这段代码并不接近DRY,但是它也有同样的问题:声明后,行中的'points'被记录到控制台中,虽然在该日志中,它已经被交换了?这怎么可能,因为还没有命令说它这样做。 JavaScript如何处理这种代码的和平?为什么我的工作似乎没有?

**第一个日志的预期输出是:[[1,2],[10,20],[100,200]] **和第二个日志:[[1,2],[100,200],[10, 20]

StackOverFlow snipped按预期运行它,但Chrome运行它的方式不同

javascript arrays google-chrome lazy-evaluation console.log
2个回答
8
投票

我相信这里发生的事情是控制台显示的内容(在Firefox中):

initial console

但是,然后单击以展开它以查看数组内部,项目被交换:

expanded console

这是因为控制台实际上是向您显示对数组的引用,并且由于您的算法修改了原始数组,因此当您单击以在控制台中展开元素时,该引用已被修改。您的代码很好,您可以尝试使用.toString()JSON.stringify甚至[...points]来确保每行中控制台的输出是不同的值而不是对相同值的引用。

使用console.log(points.toString())运行您的确切算法,我看到了这一点(再次在Firefox中):

toString demo

仅出于演示目的,以下是如何使用结构化赋值简化代码以执行相同操作:

var points = [[1, 2], [10, 20], [100, 200]];
console.log(points.toString());
[points[1], points[2]] = [points[2], points[1]];
console.log(points.toString());

0
投票

p.s.w.g是正确的,这与Chrome对console.log之类的数组的懒惰eval有关。这里有更多细节:Is Chrome's JavaScript console lazy about evaluating arrays?

© www.soinside.com 2019 - 2024. All rights reserved.