浅拷贝
Object.assign
Object.assign()
方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
注意
Object.assign 会跳过那些值为 null 或 undefined 的源对象。
const target = { a: 1, b: 2 }; const source = { b: 4, c: 5 }; const returnedTarget = Object.assign(target, source); console.log(target); // expected output: Object { a: 1, b: 4, c: 5 } console.log(returnedTarget); // expected output: Object { a: 1, b: 4, c: 5 }
[].concat
[].concat
复制数组, 类似于对于对象的复制, 可以使用 [].concat
进行数组的深复制
var list = [1, 2, 3]; var changedList = [].concat(list); changedList[1] = 2; list === changedList; // false
同样 concat 方法只能保证一层深复制
> list = [[1,2,3]] [ [ 1, 2, 3 ] ] > new_list = [].concat(list) [ [ 1, 2, 3 ] ] > new_list[0][0] = 4 4 > list [ [ 4, 2, 3 ] ]
注意
浅拷贝会出现引用混乱的问题
const object1 = { title: { text: 'hello object1', value: '1' } } const obj1 = Object.assign({}, object1) const obj2 = Object.assign({}, object1) obj2.title.text = 'hello world' console.log('obj1') console.log(obj1) // { title: { text: 'hello world', value: '1' } } console.log('obj2') console.log(obj2) // { title: { text: 'hello world', value: '1' } } console.log('object1') console.log(object1) // { title: { text: 'hello world', value: '1' } }
深拷贝
递归属性遍历
由于原型不应该被赋予给新对象,在遍历的过程中,使用hasOenProperty方法过滤掉那些继承自原型链上的属性
const object1 = { title: { text: 'hello object1', value: '1' } } function clone (obj) { let copy // Handle the 3 simple types, and null or undefined if (null == obj || 'object' != typeof obj) return obj // Handle Date if (obj instanceof Date) { copy = new Date() copy.setTime(obj.getTime()) return copy } // Handle Array if (obj instanceof Array) { copy = [] for (var i = 0, len = obj.length; i < len; i++) { copy[i] = clone(obj[i]) } return copy } // Handle Object if (obj instanceof Object) { copy = {} for (var attr in obj) { if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]) } return copy } throw new Error(`Unable to copy obj! Its type isn't supported.`) } let obj3 = clone(object1) console.log(obj3) // { title: { text: 'hello object1', value: '1' } } obj3.title.text = 'hi !' console.log(obj3) // { title: { text: 'hi !', value: '1' } } console.log(object1) // { title: { text: 'hello object1', value: '1' } }
利用JSON深拷贝
JSON.parse(JSON.stringify(obj))
JSON复制会忽略掉值为undefined以及函数表达式
const object2 = { title: { text: 'object2', value: '2', age: undefined, name: null, sum: function() { return 1 } } } let obj4 = JSON.parse(JSON.stringify(object2)) console.log(obj4) // { title: { text: 'object2', value: '2', name: null } } obj4.title.text = 'obj4' console.log(obj4) // { title: { text: 'obj4', value: '2', name: null } } console.log(object2) // { title: { text: 'object2', value: '2', age: undefined, name: null, sum: [Function: sum] } }