We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Object.assign(target, source)
let a = { age: 1 } let b = Object.assign({}, a) a.age = 2 console.log(b.age) // 1
...
let a = { age: 1 } let b = { ...a } a.age = 2 console.log(b.age) // 1
JSON.stringify(obj) / JSON.parse(str)
let a = { age: 1, jobs: { first: 'FE' } } let b = JSON.parse(JSON.stringify(a)) a.jobs.first = 'native' console.log(b.jobs.first) // FE
但是该方法也是有局限性:
以下代码会报错:
let obj = { a: 1, b: { c: 2, d: 3, }, } obj.c = obj.b obj.e = obj.a obj.b.c = obj.c obj.b.d = obj.b obj.b.e = obj.b.c let newObj = JSON.parse(JSON.stringify(obj)) console.log(newObj)
这里包含循环引用对象,无法实现深拷贝。
MessageChanel
function structuralClone(obj) { return new Promise(resolve => { const { port1, port2 } = new MessageChannel() port2.onmessage = ev => resolve(ev.data) port1.postMessage(obj) }) } var obj = { a: 1, b: { c: 2 } } obj.b.d = obj.b // 注意该方法是异步的 // 可以处理 undefined 和循环引用对象 const test = async () => { const clone = await structuralClone(obj) console.log(clone) } test()
Date, RegExp
此时代码为:
function clone (obj) { if (obj == null) return obj if (obj instanceof Date) return new Date(obj) if (obj instanceof RegExp) return new RegExp(obj) // 可能是对象或者普通的值,若为函数,则不需要深拷贝 if (typeof obj !== 'object') return obj let cloneObj = new obj.constructor for (let k in obj) { if (obj.hasOwnProperty(k)) { cloneObj[k] = obj[k] } } return cloneObj } let obj = { name: 1, date: new Date(), reg: new RegExp("\\w+"), address: {x: 1000} } let d = clone(obj) console.log('obj', obj) console.log('d', d) console.log('obj === d', obj === d)
function deepClone(obj, hash = new WeakMap()) { if (obj == null) return obj if (obj instanceof Date) return new Date(obj) if (obj instanceof RegExp) return new RegExp(obj) // 可能是对象或者普通的值,若为函数,则不需要深拷贝 if (typeof obj !== 'object') return obj // 若为对象,则进行深拷贝 if (hash.get(obj)) return hash.get(obj) // [], {} , Object.prototype.toString.call(obj) === '[Object Array]' ? [] : {} let cloneObj = new obj.constructor hash.set(obj, cloneObj) for (let k in obj) { if (obj.hasOwnProperty(k)) { // 递归拷贝 cloneObj[k] = deepClone(obj[k], hash) } } return cloneObj } let obj = {name: 1, address: {x: 100}} obj.o = obj let d = deepClone(obj) obj.address.x = 300 console.log('d', d) console.log('obj', obj) console.log('obj === d', obj === d) // 若对象复杂一些,循环引用
其他方式
const v8 = require('v8') const list = [1,2,3, {name: 'hey'}, [1,2,3]] let list2 = v8.deserialize(v8.serialize(list)); list2[3].name = 'hi~' list2[4].shift() console.log('list', list) console.log('list2', list2) // list [ 1, 2, 3, { name: 'hey' }, [ 1, 2, 3 ] ] // list2 [ 1, 2, 3, { name: 'hi~' }, [ 2, 3 ] ]
参考资料:
The text was updated successfully, but these errors were encountered:
No branches or pull requests
浅拷贝
Object.assign(target, source)
...
深拷贝
JSON.stringify(obj) / JSON.parse(str)
, 具体原理参考 JSON-MDN但是该方法也是有局限性:
以下代码会报错:
这里包含循环引用对象,无法实现深拷贝。
MessageChanel
Date, RegExp
此时代码为:
其他方式
参考资料:
The text was updated successfully, but these errors were encountered: