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? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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: