浅克隆
1.对象克隆:Object.assign(目标对象, ...源对象) && $.extend(目标对象, ...源对象)
let person = { name: 'LQW', age: 23, school: { senior: 'mengnitan', university: 'TJ university' }, friends: ['lq', 'hxy', 'nxl', 'ssy', 'kxl'], sayHello: function () { console.log('hello'); } }; let nPerson = Object.assign({}, person);
// let nPerson = $.extend({}, person); // jquery的$.extend用法一致
console.log(nPerson);
备注:
如果目标对象中的属性具有相同的键,则属性将被源中的属性覆盖。后来的源的属性将类似地覆盖早先的属性。Object.assign
方法只会拷贝源对象自身的并且可枚举的属性到目标对象。该方法使用源对象的[[Get]]
和目标对象的[[Set]]
,所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。如果合并源包含getter,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到原型,应使用Object.getOwnPropertyDescriptor()
和Object.defineProperty()
。
2. 数组克隆:
const arr = [1, 2, 3]; const cloneArr = arr.concat([4]); console.log(cloneArr);
深克隆
1.利用JSON api
let person = { name: 'LQW', age: 23, school: { senior: 'mengnitan', university: 'TJ university' }, friends: ['lq', 'hxy', 'nxl', 'ssy', 'kxl'], sayHello: function () { console.log('hello'); } }; let nPerson = JSON.parse(JSON.stringify(person)); console.log(nPerson)
备注:此方法的缺点是对象里面的函数不会被克隆
2.使用递归实现深克隆
function isType (data) { return Object.prototype.toString.call(data).slice(8, -1).toLowerCase(); } function deepClone (data) { let nData, dataType = isType(data); if (dataType === 'object') { console.log('对象'); nData = {}; } else if (dataType === 'array') { console.log('数组'); nData = []; } else { console.log('原始类型'); return data; } console.log(data); for (var key in data) { if (isType(data[key] === 'object') || isType(data[key] === 'array')) { nData[key] = deepClone(data[key]); } else { nData[key] = data[key]; } } return nData; } let person = { name: 'LQW', age: 23, school: { senior: 'mengnitan', university: 'TJ university' }, friends: ['lq', 'hxy', 'nxl', 'ssy', 'kxl'], sayHello: function () { console.log('hello'); } }; let nPerson = deepClone(person); console.log(nPerson); console.log(person);