什么是浅拷贝?如何实现浅拷贝?什么是深拷贝?如何实现深拷贝?
对象类型在赋值的过程中其实是复制了地址,从而会导致改变了一方其他也都被改变的情况。通常在开发中我们不希望出现这样的问题,我们可以使用浅拷贝和深拷贝来解决问题;但是浅拷贝只解决了第一层的问题,如果里面的值有对象的话就需要用深拷贝了
★ 浅拷贝
1.Object.assign
2.展开运算符 ...
★ 深拷贝
1.JSON.parse(JSON.stringify(object))
但是该方法也是有局限性的:
- 会忽略
undefined - 会忽略
symbol - 不能序列化函数
- 不能解决循环引用的对象
- 在遇到函数、
undefined或者symbol的时候,该对象也不能正常的序列化
2.MessageChannel
3.lodash 的深拷贝函数
// 使用
import _ = form 'lodash';
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);// => false
4.自定义深拷贝
function deepClone(obj) {
function isObject(o) {
return (typeof o === 'object' || typeof o === 'function') && o !== null
}
if (!isObject(obj)) {
throw new Error('非对象')
}
let isArray = Array.isArray(obj)
let newObj = isArray ? [...obj] : { ...obj }
Reflect.ownKeys(newObj).forEach(key => {
newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
})
return newObj
}
let obj = {
a: [1, 2, 3],
b: {
c: 2,
d: 3
}
}
let newObj = deepClone(obj)
newObj.b.c = 1
console.log(obj.b.c) // 2
★ Reflect.ownKeys和Object.keys的区别
jishuin.proginn.com/p/763bfbd64…
1.关于对象属性是否可枚举
Reflect.ownKeys()可以得到对象自己的所有属性,包括不可枚举属性;
Object.keys()只能得到对象的普通可枚举属性,拿不到不可枚举属性。
2.关于Symbol属性
Reflect.ownKeys()可以拿到对象的Symbol 的属性;
Object.keys()不行。
3.关于数组的length属性
因为Reflect.ownKeys()可以得到对象的不可枚举属性这个特点,所以当目标对象是数组对象时,我们可以看到获取的结果会比Object.keys()多一个length属性
事实证明,数组的length也确实是“不可枚举的”:
4.关于对象的原型
俩人这点上谁也不比谁强,都拿不到原型链上的属性。
不过还好,这点需求上,可以用for...in来替代。
总结表格
| 方法分类 | 普通属性 | 不可枚举属性 | Symbol属性 | 原型属性 | 数组length |
|---|---|---|---|---|---|
Reflect.ownKeys() | ✅ | ✅ | ✅ | ❌ | ✅ |
Object.keys() | ✅ | ❌ | ❌ | ❌ | ❌ |
for...in | ✅ | ❌ | ❌ | ✅ | ❌ |