共计 749 个字符,预计需要花费 2 分钟才能阅读完成。
在 ES6 的系列文章中,基本都会提到 Spread
——扩展运算符(...
) 的使用。伴随着这个运算符的出现,也往往会牵扯出其他一些问题,深拷贝 和浅拷贝 就是其中之一。
相关背景
在讨论 深拷贝 和浅拷贝 之前,我们先看一个例子:
let a = 'hi';
b = a;
b = 'hello';
console.log(a);
// 'hi'
let arr1 = [1,2,3];
arr2 = arr1;
arr2[0] = 0;
console.log(arr1);
// [0,2,3]
可以看到:为不同的 js 变量复制值时,结果是不同的。把字符串 a
的值复制给 b
,改变b
的值不会影响 a
的值,而把数组 arr1
的值复制给 arr2
时,改变 arr2
的值,arr1
的值也跟着改变了。
这是因为 js 存在两种不同数据类型的值:基本类型值
和引用类型值
。
在访问这两种类型的变量时,其访问方式是不同的。在这里,先记一下结论:
- 基本数据类型是 按值访问的
- 引用数据类型是 按引用访问的
( 实际上这种说法并不严密,为便于理解,我们先这么记)
什么意思?
JavaScript 不允许直接访问内存中的位置,换句话说,不能直接操作对象的内存空间。
因此,在操作对象时,我们实际上是在操作对象的引用,而不是实际的对象。
从一个变量向另一个变量复制值时(不管是复制基本类型还是引用类型),都会先为这个新变量分配一个空间,然后把该值复制到新创建的这个空间里。
不同的是,在复制引用类型的值时,实际上复制过去的是一个指针,示例图如下:
在 js 中,除了 7 种基本类型外,其他的都是引用类型,比如Object
,Array
,Function
,所以不难理解:
let obj1 = {name:'hx',age:18};
let obj2 = obj1;
obj2.age = 0;
console.log(obj1);
// {name:'hx',age:0}
正文完
发表至: javascript
2019-04-30