- Object.create({}, { p: { value: 10 })创建一个对象,默认情况下已下三个数据为false
- configurable: false, //能否使用delete、能否需改属性特性、或能否修改访问器属性、,false为不可重新定义,默认值为true
- enumerable: false, //对象属性是否可通过for-in循环,false为不可循环,默认值为true
- writable: false, //对象属性是否可修改,false为不可修改,默认值为true
所有在进行深拷贝的情况下需要使用Object.getOwnPropertyDescriptors() 方法获取对象属性增加到拷贝对象中
代码展示
// 深拷贝
function deepCopy(obj, parent = null) {
let result
let _parent = parent
// 该字段有父级则需要追溯该字段的父级
while (_parent) {
// 如果该字段引用了它的父级,则为循环引用
if (_parent.originalParent === obj) {
// 循环引用返回同级的新对象
return _parent.currentParent
}
_parent = _parent.parent
}
if (obj && typeof (obj) === 'object') {
if (obj instanceof RegExp) {
result = new RegExp(obj.source, obj.flags)
// source 属性返回一个值为当前正则表达式对象的模式文本的字符串,该字符串不会包含正则字面量两边的斜杠以及任何的标志字符。
// flags 属性返回一个字符串,由当前正则表达式对象的标志组成
} else if (obj instanceof Date) {
result = new Date(obj.getTime())
} else {
if (obj instanceof Array) {
result = []
} else {
// 返回指定对象的原型
result = Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
)
}
for (let i in obj) {
if (obj[i] && typeof (obj[i]) === 'object') {
// 递归执行深拷,将同级的待拷贝对象传递给parent,方便追溯循环引用
result[i] = deepCopy(obj[i], {
originalParent: obj,
currentParent: result,
parent: parent
})
} else {
result[i] = obj[i]
}
}
}
} else {
return obj
}
return result
}
const obj = Object.create({}, { p: { value: 10 , configurable: true, writable: false, enumerable: false} })
console.log(Object.getOwnPropertyDescriptors(obj), 8)
const obj2 = deepCopy(obj)
console.log(Object.getOwnPropertyDescriptors(obj2))
打印如下