Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Javascript中交换整个数组_Javascript_Arrays_Pass By Reference_Pass By Value - Fatal编程技术网

在Javascript中交换整个数组

在Javascript中交换整个数组,javascript,arrays,pass-by-reference,pass-by-value,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); 这导致u为[1,0],v为[0,1]。在调用swap函数后,这些值尚未更改 另一方面,如果我在没有函数调用的情况下执行此操作: u=[1, 0]; v=[0, 1]; var temp = u;

当我尝试创建一个交换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);
这导致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);
然后它们被正确地交换,u为[0,1],v为[1,0]


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

Javascript不能传递对u和v变量本身的引用。因此,在交换函数中对x或y的赋值不会改变对u或v的赋值。Javascript将引用传递给u和v持有的对象。因此,您不能从交换中更改u和v变量。您可以更改它们指向的对象的内容,从而可以修改u和v指向的对象的属性

因为我有C/C++的背景,所以我想到了Javascript在作为传递指针传递对象时所做的事情。调用swapu,v时,传递给swap函数的是一个指向u也指向的数组的指针。现在有两个变量u和x都指向同一个数组。因此,如果修改该实际数组,那么由于u点位于同一数组中,两者都将看到修改。但是,在swap函数中所做的任何操作都不能更改对象u或v实际指向的对象

在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);
如果不介意从头重写两个数组,可以将一个数组的所有内容复制到临时数组,然后将一个数组复制到另一个数组,然后将临时数组内容复制回第一个原始数组。这不是很有效,可能有更好的方法来解决您原来的问题,但这是可以做到的

 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);
 }

Javascript不能将引用传递给u和v变量本身。因此,在交换函数中对x或y的赋值不会改变对u或v的赋值。Javascript将引用传递给u和v持有的对象。因此,您不能从交换中更改u和v变量。您可以更改它们指向的对象的内容,从而可以修改u和v指向的对象的属性

因为我有C/C++的背景,所以我想到了Javascript在作为传递指针传递对象时所做的事情。调用swapu,v时,传递给swap函数的是一个指向u也指向的数组的指针。现在有两个变量u和x都指向同一个数组。因此,如果修改该实际数组,那么由于u点位于同一数组中,两者都将看到修改。但是,在swap函数中所做的任何操作都不能更改对象u或v实际指向的对象

在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);
如果不介意从头重写两个数组,可以将一个数组的所有内容复制到临时数组,然后将一个数组复制到另一个数组,然后将临时数组内容复制回第一个原始数组。这不是很有效,可能有更好的方法来解决您原来的问题,但这是可以做到的

 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);
 }

它们通过引用传递,但也通过引用进行赋值。当您写入x=y时,您并没有修改任何一个数组,您只是让您的局部变量x引用与y相同的数组

如果要交换数组内容,必须修改数组本身:

function swap(x,y) {
    var temp = x.slice(0);
    x.length = 0;
    [].push.apply( x, y );
    y.length = 0;
    [].push.apply( y, temp ); 
}

它们通过引用传递,但也通过引用进行赋值。当您写入x=y时,您并没有修改任何一个数组,您只是让您的局部变量x引用与y相同的数组

如果要交换数组内容,必须修改数组本身:

function swap(x,y) {
    var temp = x.slice(0);
    x.length = 0;
    [].push.apply( x, y );
    y.length = 0;
    [].push.apply( y, temp ); 
}

获取这些参考/价值问题的术语很棘手,但我会尽全力


对象/数组变量的内容实际上只是引用。与C++不同,说X= Y实际上不将对象的变量复制到新的内存位置。在内部,它只是在上面复制一个指针位置。该语言不具备自动在新实例中重新创建对象或数组之类的结构;如果出于某种原因,您希望维护一个数组的两个副本,则需要显式创建它,然后在值上进行复制,即,=[];or=新数组;或者像=oldArray.map这样的复制函数

一个可能在概念上有所帮助的小代码示例。这些规则同样适用于对象和数组

a = {}; // In case you haven't seen it, this is like shorthand of "new Object();"
b = {};
c = b;
console.log(a === b); // false
console.log(b === c); // true
b.property = "hello";
console.log(c.property) // hello

获取这些参考/价值问题的术语很棘手,但我会尽全力


对象/数组变量的内容实际上只是引用。不像C++,说x= y不 实际上,将对象的变量复制到新的内存位置。在内部,它只是在上面复制一个指针位置。该语言不具备自动在新实例中重新创建对象或数组之类的结构;如果出于某种原因,您希望维护一个数组的两个副本,则需要显式创建它,然后在值上进行复制,即,=[];or=新数组;或者像=oldArray.map这样的复制函数

一个可能在概念上有所帮助的小代码示例。这些规则同样适用于对象和数组

a = {}; // In case you haven't seen it, this is like shorthand of "new Object();"
b = {};
c = b;
console.log(a === b); // false
console.log(b === c); // true
b.property = "hello";
console.log(c.property) // hello


就像Java一样,JavaScript只通过值传递。赋值给函数中的局部变量对函数之外的任何东西都不会有任何影响。

就像Java一样,JavaScript只是按值传递。赋值给函数中的局部变量不会对函数之外的任何内容产生任何影响。

预期的输出是什么?u和v应该互换。所以u应该是[0,1],v应该是[1,0]。在这个问题中,我也会说得更清楚。数组没有被复制并不意味着它们是通过引用传递的。这更类似于通过指针传递。我认为Javascript数组是通过引用传递的,而不是通过值传递的。我是不是误解了什么?是的,JavaScript只有传递值。值的类型是不相关的。预期的输出是什么?u和v应该交换。所以u应该是[0,1],v应该是[1,0]。在这个问题中,我也会说得更清楚。数组没有被复制并不意味着它们是通过引用传递的。这更类似于通过指针传递。我认为Javascript数组是通过引用传递的,而不是通过值传递的。我是不是误解了什么?是的,JavaScript只有传递值。值的类型是不相关的。我在C++中使用了STD::SWAP。有没有一种方法可以在Javascript中实现同样的功能?这是通过引用传递的。在像C这样的语言中,只能按值传递引用,但可以按值传递引用,因此也可以按值传递引用到references,这允许OP的行为expecting@user3448821-在Javascript中,模拟真实引用(允许您更改原始变量包含的内容)的唯一方法是根据对象的属性生成u和v并传递包含的对象。然后,你可以交换这两个属性的内容。@ USSR48821-我用一个对象交换了我的答案。@ PulPro我试图清理我在回答你的评论中使用的术语。我用了STD::在C++中交换。有没有一种方法可以在Javascript中实现同样的功能?这是通过引用传递的。在像C这样的语言中,只能按值传递引用,但可以按值传递引用,因此也可以按值传递引用到references,这允许OP的行为expecting@user3448821-在Javascript中,模拟真实引用(允许您更改原始变量包含的内容)的唯一方法是根据对象的属性生成u和v并传递包含的对象。然后,您可以交换这两个属性的内容。@user3448821-我在回答中添加了一个使用对象交换的示例。@Paulpro-我试图清理我在回答中使用的术语来处理您的评论。只是为了澄清,这不是真正的交换。这是从头开始重写两个数组,效率不是特别高。也许这就是OP想要的,但我肯定不会用通常意义上的交换来称呼它。@jfriend00同意。这个答案是Θn,而使用容器对象的解决方案是Θ1。它还使用额外的内存,因为它复制x。对于小型阵列,它们的速度大致相同,但对于大型阵列,您的速度肯定会优于此速度。我想说这个版本更容易阅读和使用,它们不是通过引用传递的。语义与Java中的完全相同。Java在堆栈溢出上被普遍描述为没有传递引用,只是要清楚,这并不是真正的交换。这是从头开始重写两个数组,效率不是特别高。也许这就是OP想要的,但我肯定不会用通常意义上的交换来称呼它。@jfriend00同意。这个答案是Θn,而使用容器对象的解决方案是Θ1。它还使用额外的内存,因为它复制x。对于小型阵列,它们的速度大致相同,但对于大型阵列,您的速度肯定会优于此速度。我想说这个版本更容易阅读和使用,它们不是通过引用传递的。语义与Java中的完全相同。java在堆栈溢出上被普遍描述为没有引用传递。与C++不同,X= Y实际上不将对象的变量复制到新的内存位置。它就像C++中的C++一样,它将是fo*y=…Foo*x=y;结构是一样的。@newacct承认我认为我们用不同的词汇说同样的话,但我不同意
我不确定我是否同意这种相似性。在两行示例中,您正在声明一个包含指针的变量。然后,创建另一个变量,在我看来,将指针复制到一个新的内存位置。编译器确实必须为这些新的32/64位进行分配。所以,如果C++总是只与指针一起工作,那么我理解的每一个对象都是一个危险的实践,它只需要应用到任何地方,而这正是JavaScript代码所说的。类型不是用JavaScript编写的。与C++不同的是,X= Y实际上并不将对象的变量复制到新的内存位置。它就像C++中的C++一样,它将是fo*y=…Foo*x=y;结构是一样的。@newacct承认,我认为我们用不同的词汇说同一件事,但我不确定我是否同意这种相似性。在两行示例中,您正在声明一个包含指针的变量。然后,创建另一个变量,在我看来,将指针复制到一个新的内存位置。编译器确实必须为这些新的32/64位进行分配。所以,如果C++总是只与指针一起工作,那么我理解的每一个对象都是一个危险的实践,它只需要应用到任何地方,而这正是JavaScript代码所说的。类型不是用JavaScript写出来的。