深克隆、浅复制的基本定义
浅复制(浅克隆):直接将存储在栈中的值赋值给对应变量,如果是基本数据类型,则直接赋值对应的值,如果是引用类型,则赋值的是地址 深复制(深克隆):就是把数据赋值给对应的变量,从而产生一个与源数据不相干的新数据(数据地址已变化)。深拷贝,是拷贝对象各个层级的属性。
基本类型赋值(以string为例)
基本类型: 字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol(es6新增)。
let a = '你好'
let b = a
a = '我很好'
console.log(a) // 你好
console.log(b) // 我很好
// 基本类型赋值,a变化并不会影响b。
// 基本数据类型是直接存储在栈内存中的
引用类型赋值(以Array为例)
引用类型:对象(Object)、数组(Array)、函数(Function)。
let arr = [1, 2, 3, 4]
let newArr = arr
arr = [5, 6, 7, 8]
console.log(arr) // [5, 6, 7, 8]
console.log(newArr) // [5, 6, 7, 8]
// 引用类型赋值,arr改变会导致newArr改变
// 引用数据类型,则仅仅是把地址存储在栈内存中,真正的数据是存储在堆内存中的,赋值操作时,仅仅把地址进行了赋值
实现深克隆的几种方法
递归
function deepClone(target) {
if (target === null) return null;
if (typeof target !== 'object') return target;
const cloneTarget = Array.isArray(target) ? [] : {};
for (let prop in target) {
if (target.hasOwnProperty(prop)) {
// Object.prototype.hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)
cloneTarget[prop] = deepClone(target[prop]);
}
}
return cloneTarget;
}
let arr = {
name: '张三',
age: '30',
children:[
{
name: '老大',
age: '14'
},
{
name: '老二',
age: '10'
}
]
}
let newArr = deepClone(arr)
arr = {
name: '李四',
age: '50',
children:[
{
name: '老大',
age: '20'
},
{
name: '老二',
age: '19'
}
]
}
console.log(newArr) // 对象name为张三
console.log(arr) // 对象name为李四
JSON.stringify 和 JSON.parse(对象中的属性值不能是函数、undefined以及symbol值)
let arr = {
name: '张三',
age: '30',
children:[
{
name: '老大',
age: '14'
},
{
name: '老二',
age: '10'
}
]
}
let newArr = JSON.parse(JSON.stringify(arr))
arr = {
name: '李四',
age: '50',
children:[
{
name: '老大',
age: '20'
},
{
name: '老二',
age: '19'
}
]
}
console.log(newArr) // 对象name为张三
console.log(arr) // 对象name为李四
实现浅克隆
浅克隆:如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
对象浅克隆
let arr = {
name: '张三',
age: '30'
}
let newArr = Object.assign({},arr)
arr = {
name: '李四',
age: '50'
}
console.log(newArr) // 对象name为张三
console.log(arr) // 对象name为李四