深拷贝与浅拷贝与赋值之间的关系
var person1 = {
name: "张三",
age: "45",
children: {
name: "张心",
age: '12',
},
arr: [1,[2,3],4,5]
}
赋值
var person2 = person1
person2.name = '李四'
person2.children.name = '李四海';
person2.arr[1][1] = 'm'
console.log(person1)
// {name: "李四", age: "45",children: {name: "李四海", age: "12"},arr: [1,[2,'m'],4,5]
可以看到 赋值 改变 person2 会直接改变 person1 ,这是因为 赋值 属于 只是说改了个名字,但他们在内存中指向同一个地址
基本类型与引用类型
基本数据类型主要是:undefined,boolean,number,string,null
// 基本类型是值的比较 放在栈中
var a = 1 b = true;
console.log(a == b) // true
// 基本数据类型不可变
var str = '123'
str[1] = 'f'
console.log(str) // 123
// 基本类型的赋值的两个变量是两个独立相互不影响的变量
var a = 1;
var b = a;
a++
console.log(a) // 2
console.log(b) // 1
// 引用类型是引用的比较 放在堆中
var arr1 = [1,2,3]
var arr2 = [1,2,3]
console.log(arr1 == arr2) // false
// 引用类型的赋值 是 地址的传递
var a = [1,2,3,4]
var b = a;
b[1] = 'm'
console.log(a) // [1,'m',3,4]
console.log(b) // [1,'m',3,4]
// a 和 b 指向同一内存中的地址
言归正传
浅拷贝 对基本的值类型进行值传递,对引用类型进行 址 传递
// 浅拷贝 结果 只会 影响 基本类型,不会 影响 引用类型
function shallowClone(obj){
var shallowCloneObj = new obj.constructor()
for(var key in obj){
if(obj.hasOwnProperty(key)){
shallowCloneObj[key] = obj[key]
}
}
return shallowCloneObj;
}
person3 = shallowClone(person1)
person3.name = "王五"
person3.children.name = "王浩"
person3.arr[1] = 'w'
console.log(person3)
// {name: "王五", age: "45",children: {name: "王浩", age: "12"},arr: (4) [1, "w", 4, 5]
console.log(person1)
// {name: "张三", age: "45",children: {name: "王浩", age: "12"},arr: (4) [1, "w", 4, 5]
// 不出意外,浅拷贝 只能更改 基本类型 , 对引用类型还是指向原来的内存,导致更改 也会影响原数据
深拷贝 对基本的值类型进行值传递,对引用类型,创建一个对象,并返回其内容
就是说深拷贝过来的数据,操作 不会影响原数据
function deepClone(obj){
if (obj === null) return obj;
// 解决 日期和正则拷贝问题
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
if (typeof obj !== "object") return obj; // 停止递归
var deepCloneObj= new obj.constructor()
for(var key in obj){
if(obj.hasOwnProperty(key)){
// 这里需要递归一下,使得引用类型 也 更换内存地址并赋值内容
deepCloneObj[key] = deepClone(obj[key])
}
}
return deepCloneObj;
}
person3 = deepClone(person1)
person3.name = "王五"
person3.children.name = "王浩"
person3.arr[1] = 'w'
console.log(person3)
// {name: "王五", age: "45",children: {name: "王浩", age: "12"},arr: (4) [1, "w", 4, 5]
console.log(person1)
// {name: "张三", age: "45",children: {name: "张心", age: "12"},arr: [1,[2,3],4,5]
// 进行深拷贝后,拷贝过来的数据就和原数据没有一点儿关系了
最简单的深拷贝
function deepClone(obj){
let newObj = JSON.stringfy(obj),
cloneObj = JSON.parse(newObj);
return cloneObj;
}
看实际引用,酌情考虑采用哪种 拷贝 。综上就是我上次电话面试之后学习心得