在Javascript中交换整个数组

use*_*821 0 javascript arrays pass-by-reference pass-by-value

当我尝试使函数交换2个数组时,原始数组保持不变.

function swap(x, y) {
    var temp = x; x = y; y = temp;
}

u=[1, 0];
v=[0, 1];
swap(u, v);
console.log(u);
console.log(v);
Run Code Online (Sandbox Code Playgroud)

这导致u为[1,0],v为[0,1].函数调用swap后,值没有更改.

另一方面,如果我在没有函数调用的情况下执行此操作:

u=[1, 0];
v=[0, 1];
var temp = u;
u = v;
v = temp;
console.log(u);
console.log(v);
Run Code Online (Sandbox Code Playgroud)

然后它们被正确交换,u为[0,1],v为[1,0].

我认为Javascript数组是通过引用传递的,而不是通过值传递的.我在这里误解了什么吗?

jfr*_*d00 6

JavaScript并没有传递给一个参考的能力uv变量本身.因此,在您的函数中xyswap()函数中的任何赋值都不会更改分配给u或的内容v.Javascript传递对该对象的引用uv保持.因此,您无法从内部更改uv变量swap().您可以更改它们指向的对象的内容,从而可以修改uv指向的对象的属性.

由于我有一个C/C++背景,我想到了将对象作为"传递指针"传递时Javascript的作用.当你调用时swap(u, v),传递给swap()函数的是指向u也指向的数组的指针.所以,现在你有两个变量u并且x都"指向"同一个数组.因此,如果您修改该实际数组,那么由于u在同一个数组中的点,两者都将看到修改.但是,你在swap()函数内部做的任何事都不能改变对象uv实际指向的对象.


在Javascript中,改变原始变量指向的对象的唯一方法是使它们成为对象的属性并传递对象,如下所示:

function swap(obj, x, y) {
    var temp = obj[x]; obj[x] = obj[y]; obj[y] = temp;
}

var container = {};
container.u = [1, 0];
container.v = [0, 1];
swap(container, "u", "v");
console.log(container.u);
console.log(container.v);
Run Code Online (Sandbox Code Playgroud)

如果您不介意从头开始重写两个数组,可以将一个数组的所有内容复制到临时数组,然后将一个数组复制到另一个数组,然后将临时数组内容复制回第一个原始数组.这不是非常有效,并且可能有更好的方法来解决您的原始问题,但它可以完成.

 function swap(x, y) {
      // remove all elements from x into a temporary array
      var temp = x.splice(0, x.length);
      // then copy y into x
      x.push.apply(x, y);
      // clear y, then copy temp into it
      y.length = 0;
      y.push.apply(y, temp);
 }
Run Code Online (Sandbox Code Playgroud)