js里的深拷贝和浅拷贝

109 阅读2分钟

浅拷贝和深拷贝的含义

简单来说:

  1. 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用(地址)
  2. 深拷贝拷贝多层,每一级别的数据都会拷贝。

浅拷贝和深拷贝的区别

  • 在深拷贝中,新对象中的更改不会影响原对象,而在浅拷贝中,新对象中的更改,原对象中也会跟着改。
  • 在深拷贝中,原对象与新对象不共享相同的属性,而在浅拷贝中,它们具有相同的属性。
  • 简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。

浅拷贝

var arr = [{name: 'wens'},{age: '26'}];           //原数组 
var newArr1 = arr;                                //浅拷贝
var newArr2 = arr.slice();                        //浅拷贝
var newArr3 = arr.concat();                       //浅拷贝
var newArr4 = JSON.parse(JSON.stringify(arr));    //深拷贝
arr[0].name = 'leon';  
arr[1].age = '27';  
console.log(arr);
console.log(newArr1);
console.log(newArr2);
console.log(newArr3);
console.log(newArr4);

运行结果

image.png

一.数组的拷贝方法

1.通过slice方法

slice()操作数组时,不会对原数组有影响,会产出一个新的数组。

 let arr1 = [1, 42, 5, 6]
 let arr2 = arr1.slice()
 arr2[0] = 100
 console.log(arr1) // [1, 42, 5, 6]
 console.log(arr2) // [100, 42, 5, 6]

 2.通过concat方法

数组的concat()方法,能够连接两个数组,同样不会改变原来的数组。用一个空数组连接另一个数组,即可实现深拷贝。

let arr3 = ['cat', 'dog', 'pig']
let arr4 = [].concat(arr3)
arr3[2] = 'big pig'
console.log(arr3) // ['cat', 'dog', 'big pig']
console.log(arr4) // ['cat', 'dog', 'pig']

3. 通过ES6语法中 …运算符

ES6语法中的 …, 我经常在数组的深拷贝中用到。

let arr5 = [0, 0, 1]
let arr6 = [...arr5]
arr5[0] = 10000
console.log(arr5) // [10000, 0, 1]
console.log(arr6) // [0, 0, 1]

二. Object的拷贝方法

1 通过Object.assign()方法
ES6的Object.assign() Object.assign(target, …sources)用于对象的合并,将源对象中的所有可枚举属性,复制到目标对象中,并返回合并后的目标对象。后来的源对象的属性值,将会覆盖它之前的对象的属性。

let person = {
     name: 'xia',
     age: 25,
     height: 160
 }
 let otherPerson = Object.assign({}, person)
 person.age = 30

 console.log(person)
 console.log(otherPerson)

2.万能转换器 JSON.parse(JSON.stringify(obj))深拷贝已有对象,它可以深拷贝多层级的,不用担心嵌套问题。

JSON.stingify(obj)将js中的对象转换成JSON字符串

let jack = {
     name: 'jack'
 }
 console.log(jack)
 console.log(JSON.stringify(jack))

JSON.parse()将json字符串解析成对象

let obj = {
     name: '静茹秋叶'
 }
 console.log('obj: ', obj)
 console.log('json string: ', JSON.stringify(obj))

 let str = JSON.stringify(obj)
 console.log('--------------')
 console.log(str)
 console.log('str to obj: ', JSON.parse(str))