浅拷贝深拷贝
let a = [0, 1, 2, 3, 4] let b = a a[0] = 1 console.log(a, b)
你会发现,同一个Array或者Object赋值给两个不同变量时,变量指向的是同一个内存地址,所以就会造成其中一个变量改变属性值,同时改变了另外一个变量的对应属性值。
解决这种情况的方法
let a = [0, 1, 2, 3, 4] let b = a.slice() a[0] = 1 console.log(a, b)
let a = [0, 1, 2, 3, 4] // let b = a.slice() let b = a.concat() a[0] = 1 console.log(a, b)
但是如果是对象的话就不能够使用slice或者concat了,那就需要使用别的方法来实现这种效果
var b ={} var person = { name: 'wang', score: { math: 100, English: 100 } } b =person console.log(person === b); person.name = 'li'; console.log(person, b);
var b ={} var person = { name: 'wang', score: { math: 100, English: 100 } } b = Object.assign({},person); console.log(person === b); person.name = 'li'; console.log(person, b);
深拷贝
var obj = {name:'xixi',age:20,company : { name : '腾讯', address : '深圳'} }; var obj_json = JSON.parse(JSON.stringify(obj)); console.log(obj === obj_json); obj.company.name = "ali"; obj.name = "hei"; console.log(obj); console.log(obj_json);
这种方法虽然可以实现数组或对象深拷贝,但不能处理函数。
所以我就使用递归建档封装了一个深拷贝方法
// 定义检测数据类型的功能函数 function checkedType(target) { return Object.prototype.toString.call(target).slice(8, -1) } // 实现深度克隆---对象/数组 function clone(target) { // 判断拷贝的数据类型 // 初始化变量result 成为最终克隆的数据 console.log(target,'目标数组') let result, targetType = checkedType(target) if (targetType === 'object') { result = {} } else if (targetType === 'Array') { result = [] } else { return target } // 遍历目标数据 for (let i in target) { // 获取遍历数据结构的每一项值。 let value = target[i] // 判断目标结构里的每一值是否存在对象/数组 if (checkedType(value) === 'Object' || checkedType(value) === 'Array') { //对象/数组里嵌套了对象/数组 // 继续遍历获取到value值 result[i] = clone(value) } else { // 获取到value值是基本的数据类型或者是函数。 result[i] = value; } } return result } var obj1 = {name:'xixi',age:20,company : { name : '腾讯', address : '深圳'} }; var obj_json = clone(obj1); console.log(obj1 === obj_json); obj1.company.name = "ali"; obj1.name = "hei"; console.log(obj1); console.log(obj_json);