在Javascript中分配对象:浅复制还是深复制?

27 浏览
0 Comments

在Javascript中分配对象:浅复制还是深复制?

我想知道在复制对象时,JavaScript是浅拷贝还是深拷贝。

const a = ['value1', 'value2'];
const b = ['value3', 'value4'];
const new_ab = [a, b];

new_ab会有新分配的值还是一个引用?如果是深拷贝,我如何让它变成浅拷贝?谢谢。

0
0 Comments

在JavaScript中,所有的操作都是基于引用进行的,唯一的例外是原始值存储在栈上,并且程序不需要引用来访问它们。在你的例子中,所有的变量声明都创建了新的值 - 每个都是Array的一个实例,然而从声明数组中返回的是一个引用,而不是数组本身。例如,[1, 2]是一个值(整数)数组,但[a, b]是一个引用数组。

所以...没有任何东西被复制。我们可以通过将一个对象放置在一个数组元素中来证明这一点,并检查通过新的“父”数组仍然可以访问先前分配的属性。

(为了回答你在评论中的问题,是的,你的例子比复制值更高效。)

'use strict';

const arrayOne = [];

arrayOne.someProperty = "This string is a property of `arrayOne`, " +

"accessed via the reference to it in `arrayTwo`."

const arrayTwo = [arrayOne];

span.innerHTML = arrayTwo[0].someProperty;

"the only exception being that primitive values are kept on the stack and a program does not therefore require a reference to" 你怎么知道的?你能引用规范吗?而且,这对闭包是如何工作的呢?

并不是所有的原始值都存储在堆栈上。这些值的处理方式是规范的一个实施细节。当闭包需要一个原始值时,编译器会将该值放入堆中。关于引用的更多信息可以参考这里和这里,虽然这些只是一些经验性的观察,没有读取v8源代码的话这些就是我所能提供的了。:)

我承认我对这个引用的说法有些宽泛,但是将原始值存储在堆栈上的原则在许多面向对象的编程语言中是成立的。当发生强制转换和其他类似操作,或者像你说的在闭包中引用一个值时,这个原则可能会被颠覆。

这就是我的观点:这是一个实施细节,不是普遍的真理,所以这个说法是不正确的。在我看来,这也与问题无关。

好吧,我觉得这是一个有趣的小贴士!

0