浅拷贝深拷贝


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);