js中深克隆,浅复制详解,及实现深克隆方法

1,714 阅读2分钟

深克隆、浅复制的基本定义

浅复制(浅克隆):直接将存储在栈中的值赋值给对应变量,如果是基本数据类型,则直接赋值对应的值,如果是引用类型,则赋值的是地址 深复制(深克隆):就是把数据赋值给对应的变量,从而产生一个与源数据不相干的新数据(数据地址已变化)。深拷贝,是拷贝对象各个层级的属性。

基本类型赋值(以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为李四