赋值、浅拷贝、深拷贝关系以及实现

在探讨这个问题之前,首先得了解ECMAScript 的数据类型

ECMAScript 的数据类型

ECMAScript 的数据类型

其次是堆和栈的区别

堆和栈的区别

其实深拷贝和浅拷贝的主要区别就是其在内存中的存储类型不同。

堆和栈都是内存中划分出来用来存储的区域。

栈(stack)为自动分配的内存空间,它由系统自动释放。

堆(heap)内存是动态分配的内存,大小不定也不会自动释放。一般由程序员分配释放,若程序员不释放,程序结束时可能由垃圾回收机制回收。

基本(原始)数据类型(Undefined、Null、Boolean、Number、String)的值直接保存在栈中

引用(复杂)数据类型(对象、数组和函数)的值保存在堆中,通过使用在栈中保存对应的指针来获取堆中的值

对原数据影响

和原数据是否指向同一对象 第一层数据为基本数据类型 原数据中包含子对象
赋值 改变会使原数据一同改变 改变会使原数据一同改变
浅拷贝 改变会使原数据一同改变 改变会使原数据一同改变
深拷贝 改变会使原数据一同改变 改变会使原数据一同改变

总结

浅拷贝

浅拷贝指的是将一个对象的属性值复制到另一个对象,如果有的属性的值为引用类型的话,那么会将这个引用的地址复制给对象,因此两个对象会有同一个引用类型的引用。所以说,浅拷贝只复制一层对象的属性,并不包括对象里面的为引用类型的数据。

深拷贝

深拷贝相对浅拷贝而言,如果遇到属性值为引用类型的时候,它新建一个引用类型并将对应的值复制给它,因此对象获得的一个新的引用类型而不是一个原有类型的引用。

实现方式

浅拷贝

1.Object.assign(target, ...sources)

1
2
3
4
5
6
let a = {
age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1

2.扩展运算符 ...

1
2
3
4
5
6
let a = {
age: 1
}
let b = { ...a }
a.age = 2
console.log(b.age) // 1

3.遍历+hasOwnProperty()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 浅拷贝的实现;

function shallowCopy(object) {
// 只拷贝对象
if (!object || typeof object !== "object") return;

// 根据 object 的类型判断是新建一个数组还是对象
let newObject = Array.isArray(object) ? [] : {};

// 遍历 object,并且判断是 object 的属性才拷贝
for (let key in object) {
if (object.hasOwnProperty(key)) {
newObject[key] = object[key];
}
}

return newObject;
}

深拷贝

1.JSON.parse(JSON.stringify(object))

1
2
3
4
5
6
7
8
9
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // FE

但是该方法也是有局限性的

  • 会忽略 undefined
  • 会忽略 symbol
  • 不能序列化函数
  • 不能解决循环引用的对象

2.递归+hasOwnProperty()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 深拷贝的实现;

function deepCopy(object) {
if (!object || typeof object !== "object") return;

let newObject = Array.isArray(object) ? [] : {};

for (let key in object) {
if (object.hasOwnProperty(key)) {js
newObject[key] =
typeof object[key] === "object" ? deepCopy(object[key]) : object[key];
}
}

return newObject;
}

参考文章

js 深拷贝 vs 浅拷贝

js 中的深浅拷贝实现


评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×