赋值
基本数据类型(string, number, boolean, null, undefined, Symbol): 赋值,两个变量互不影响
1
2
3
4
5let a = 'haha';
let b = a;
a = 'hahaha';
console.log(a); // hahaha
console.log(b); // haha引用数据类型(object): 赋址,两个变量具有相同的引用,指向同一个对象,相互之间有影响
1
2
3
4
5
6
7
8
9
10
11
12let a = {
name: 'haha',
book: {
title: 'JS',
price: 40
}
}
let b = a;
a.name = 'hahaha';
a.book.price = 50;
console.log(a); // {name: 'hahaha', book: {title: 'JS', price: 50}}
console.log(b); // {name: 'hahaha', book: {title: 'JS', price: 50}}
浅拷贝
概念
创建一个对象,有原始对象属性值的一份精确拷贝。
基本类型: 拷贝值
引用类型: 拷贝内存地址,其中一个对象改变了地址,会影响到另一个对象场景
Object.assign()
1
2
3
4
5
6
7
8
9
10
11
12let a = {
name: 'haha',
book: {
title: 'JS',
price: 40
}
}
let b = Object.assign({}, a);
a.name = 'hahaha';
a.book.price = 50;
console.log(a); // {name: 'hahaha', book: {title: 'JS', price: 50}}
console.log(b); // {name: 'haha', book: {title: 'JS', price: 50}}Spread展开运算符
同Object.assign()- slice()
slice() 方法返回一个新的数组对象,这一对象是一个由 begin和 end(不包括end)决定的原数组的浅拷贝。原始数组不会被改变。1
2
3
4
5
6let a = [0, "1", [2, 3]];
let b = a.slice(1);
a[1] = "99";
a[2][0] = 4;
console.log(a); // [0, "99", [4, 3]]
console.log(b); // ["1", [4, 3]]
深拷贝
深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。
使用场景
JSON.parse(JSON.stringfy(object))1
2
3
4
5
6
7
8
9
10
11
12let a = {
name: "haha",
book: {
title: "JS",
price: 45
}
}
let b = JSON.parse(JSON.stringify(a));
a.name = 'change';
a.book.price = 100;
console.log(a); // {name: 'change', book: {title: 'JS', price: 100}}
console.log(b); // {name: 'haha', book: {title: 'JS', price: 45}}问题
undefined, Symbol, 函数,会直接忽略
1
2
3
4
5
6
7
8let obj = {
name: 'haha',
a: undefined,
b: Symbol('haha'),
c: function() {}
}
let b = JSON.parse(JSON.stringfy(obj));
console.log(b); // {name: 'haha'}循环引用,会报错
- new Date情况下,转换结果不正确
- 不能处理正则
– | 和原数据是否指向同一对象 | 第一层数据为基本数据类型 | 原数据中包含子对象 |
---|---|---|---|
赋值 | 是 | 改变会使原数据一同改变 | 改变会使原数据一同改变 |
浅拷贝 | 是 | 改变不会使原数据一同改变 | 改变会使原数据一同改变 |
深拷贝 | 是 | 改变不会使原数据一同改变 | 改变不会使原数据一同改变 |