赋值(简单数据类型和引用对象不同)
简单数据类型赋值和引用数据赋值
let a = 1;
let b = a;
a = 2;
console.log(a);//2
console.log(b);//1
console.log(a===b);//false
let arr = [1,2,3];
let arr2 = arr;
arr[0] = 3;
console.log(arr);//[3,2,3]
console.log(arr2);//[3,2,3]
console.log(arr===arr2);//true
基本数据类型保存在栈内存,引用数据保存在堆内存
复制引用对象不能简单的赋值,赋值后的数据指向同一个地址,会相互影响,所以需要浅复制或深复制
浅复制
/*数组*/
//方法1 使用from数组方法
let arr = [1,2,3];
let arr2 = Array.from(arr);
arr[0] = 3;
console.log(arr);//[3,2,3]
console.log(arr2);//[1,2,3]
console.log(arr===arr2);//false
//方法2 使用遍历(for,foreach)
let arr2 = [];
for(let i=0; i
arr2[i] = arr[i];
}
//方法3 slice
let arr2 = arr.slice();
//方法4 concat
let arr2 = arr.concat();
/*对象*/
//for..in遍历
for (let key in obj) {
obj2[key] = obj[key];
}
/*数组和对象通用*/
// 剩余参数
let arr2 = [...arr];
let obj2 = {...obj};
// assign
let arr2 = Object.assign([], arr);
let obj2 = Object.assign({}, obj);
// assign使用方法————MDN
/*const target = [1,2];
const source = [3,4];
const returnedTarget = Object.assign(target, source);
console.log(target);//{ a: 1, b: 4, c: 5 }
console.log(returnedTarget);//{ a: 1, b: 4, c: 5 }*/
浅复制只能复制引用对象元素里的简单数据,引用对象元素里的引用对象还是会互相影响
let obj = {
name: 'cidy',
age: {
a: 18,
b: 19
}
}
let obj2 = {...obj}
obj.age.a = 15;
console.log(obj);
/*{name: "cidy", age: {…}}
age: {a: 15, b: 19}
name: "cidy"
__proto__: Object*/
console.log(obj2);
/*{name: "cidy", age: {…}}
age: {a: 15, b: 19}
name: "cidy"
__proto__: Object*/
深复制
深拷贝:在计算机中开辟了一块新的内存地址用于存放复制的对象。(对属性中所有引用类型的值,遍历到是基本类型的值为止。 )
function deepCopy(obj1) {
var obj2 = Array.isArray(obj1) ? [] : {};
if (obj1 && typeof obj1 === "object") {
for (var i in obj1) {
//hasOwnPropert返回值是一个布尔值,指示对象自身属性中是否具有指定的属性,会忽略从原型链上继承到的属性
if (obj1.hasOwnProperty(i)) {
// 如果子属性为引用数据类型,递归复制
if (obj1[i] && typeof obj1[i] === "object") {
obj2[i] = deepCopy(obj1[i]);
} else {
// 如果是基本数据类型,只是简单的复制
obj2[i] = obj1[i];
}
}
}
}
return obj2;
}
var obj1 = {
a: 1,
b: 2,
c: {
d: 3
}
}
var obj2 = deepCopy(obj1);
obj2.a = 3;
obj2.c.d = 4;
alert(obj1.a); // 1
alert(obj2.a); // 3
alert(obj1.c.d); // 3
alert(obj2.c.d); // 4