Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/444.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 - Fatal编程技术网

Javascript 通过引用交换对象?

Javascript 通过引用交换对象?,javascript,Javascript,我希望使用swap函数交换两个对象,只需引用它们 典型的用例如下所示: function swap(a, b) { ... } var a = [ { id: 1 }, { id: 2 } ] swap(a[0], a[0]) console.log(a) // [ { id: 2 }, { id: 1 } ] var one = { id: 1 } var two = { id: 2 } swap(one, two) console.log(one) // Should be {

我希望使用
swap
函数交换两个对象,只需引用它们

典型的用例如下所示:

function swap(a, b) {
    ...
}

var a = [ { id: 1 }, { id: 2 } ]
swap(a[0], a[0])
console.log(a) // [ { id: 2 }, { id: 1 } ]

var one = { id: 1 }
var two = { id: 2 }
swap(one, two)
console.log(one) // Should be { id: 2 }
console.log(two) // Should be { id: 1 }
(添加了更多用例。
swap
不应依赖于任何阵列功能。)

这可能吗?我知道javascript的函数是复制引用。因此,本质上,
swap(a,b)
a
b
只是
a[0]
a[1]
的副本,因此,如果不将
a
的字段复制到
b
的字段中,我似乎无法交换它们,反之亦然,这似乎不切实际


编辑:@timolawl指出了ES6的解构,但它似乎不适用于此用例:

let a = [{ id: 1 }, { id: 2 }]

let one = a[0]
let two = a[1]

console.log(a[0])
console.log(a[1])

[one, two] = [two, one]

console.log(a[0])
console.log(a[1])

可以重构此函数以实现您想要的功能-提供数组和两个索引,并基于它们进行交换。例如:

function swap(array, a, b) {
    var temp = array[a]; // store a temporary copy of the variable

    // perform the swap
    array[a] = array[b];
    array[b] = temp;
}

请注意,临时副本是必要的,因为当您设置
array[a]=array[b]
时,数据会被覆盖,因此您必须事先存储
array[a]
的值。

可以重构此函数以完成您想要的功能-提供数组和两个索引,并基于这些索引进行交换。例如:

function swap(array, a, b) {
    var temp = array[a]; // store a temporary copy of the variable

    // perform the swap
    array[a] = array[b];
    array[b] = temp;
}
请注意,临时副本是必要的,因为当您设置
array[a]=array[b]
时,数据会被覆盖,因此您必须事先存储
array[a]
的值。

对于ES6,您可以使用:

一般情况:

[a, b] = [b, a];
例如:

let one={id:1};
设two={id:2};
document.body.insertAdjacentHTML('beforeend',''+JSON.stringify(one,0,4)+'';
document.body.insertAdjacentHTML('beforeend',''+JSON.stringify(二,0,4)+'';
[1,2]=[2,1];
document.body.insertAdjacentHTML('beforeend',''+JSON.stringify(one,0,4)+'';
document.body.insertAdjacentHTML('beforeend',''+JSON.stringify(二,0,4)+''对于ES6,您可以使用:

一般情况:

[a, b] = [b, a];
例如:

let one={id:1};
设two={id:2};
document.body.insertAdjacentHTML('beforeend',''+JSON.stringify(one,0,4)+'';
document.body.insertAdjacentHTML('beforeend',''+JSON.stringify(二,0,4)+'';
[1,2]=[2,1];
document.body.insertAdjacentHTML('beforeend',''+JSON.stringify(one,0,4)+'';

document.body.insertAdjacentHTML('beforeend',''+JSON.stringify(二,0,4)+''通过深度复制交换

没有简单的方法。Object.assign可能会有所帮助,但链中的任何属性都只是浅拷贝。还有一个笨拙的JSON副本
varb=JSON.parse(JSON.stringify(a))
但它不处理函数,并忽略所有未分配的属性,并且不能处理任何循环数据(这是所有常见的)。您可以迭代属性和原型链,并使用Object.hasOwnProperty,但对于副本应该有多深、如何解决继承等问题,您仍然不知道

通常,副本(或交换)需要了解数据的含义和上下文。有些人可能认为它不是JavaScript的一个很短的下降,而是一个通用的交换或复制函数,它打破了许多功能性编程、数据封装等的规则,所有这些规则背后都有很好的推理。p>
这就是为什么没有移动来提供方便的深度复制的原因。

通过深度复制交换

没有简单的方法。Object.assign可能会有所帮助,但链中的任何属性都只是浅拷贝。还有一个笨拙的JSON副本
varb=JSON.parse(JSON.stringify(a))
但它不处理函数,并忽略所有未分配的属性,并且不能处理任何循环数据(这是所有常见的)。您可以迭代属性和原型链,并使用Object.hasOwnProperty,但对于副本应该有多深、如何解决继承等问题,您仍然不知道

通常,副本(或交换)需要了解数据的含义和上下文。有些人可能认为它不是JavaScript的一个很短的下降,而是一个通用的交换或复制函数,它打破了许多功能性编程、数据封装等的规则,所有这些规则背后都有很好的推理。p>
这就是为什么没有移动来提供方便的深度拷贝的原因。

这对我来说不是一个选项,因为我将在复杂的状态树上为React应用程序交换。我正在尝试交换状态树中的两个对象,无论它们位于何处。@KeithYong这不是特别可能的,因为JavaScript没有指针/引用的概念。这对我来说不是一个选项,因为我将在复杂的状态树上为React应用程序交换对象。我正在尝试交换状态树中的两个对象,无论它们位于何处。@KeithYong这不是特别可能的,因为JavaScript没有指针/引用的概念。对不起,无法使用数组功能。没有正确定义用例是我的错。我在原始问题中进行了编辑,以显示它应该能够处理哪些其他用例。很高兴了解一个新的ES6函数:)@KeithYong它不必与数组一起使用。您可以将它与上面演示的两个普通变量一起使用。这就是语法!:)@timolawl这种行为总是一致的吗?例如,当第一次阅读时,我认为它可能被实现为
one=two
,然后
two=one
,结果都会变成原来的
two
@qtuan是的,交换行为是一致的。这是来自MDN关于在解构时交换变量的文章:“如果没有解构赋值,交换两个值需要一个临时变量(或XOR交换)”@timolawl您的答案对我来说很完美,但在交换存储在数组中的对象时遇到了问题。我正在试着调试它,但你能不能也检查一下,以便