引用数据类型直接赋值
- 改变变量a所指向的内存中的数据时会让另一个变量b的值改变。
let a = {
name: 'dyx'
};
let b = a;
a.name = 'douyaxing';
console.log(a); // { name: 'douyaxing' }
console.log(b); // { name: 'douyaxing' }
- 直接改变变量a的指针指向时不会让另一个变量b的值改变。
let a = {
name: 'dyx'
};
let b = a;
a = {
name: 'douyaxing'
};
console.log(a); // { name: 'douyaxing' }
console.log(b); // { name: 'dyx' }
- 改变形参arr所指向的内存中的数据时也会修改变量a。
const a = [1, 2, 3];
function test(arr) {
arr[0] = 4; // arr形参的修改也会修改变量a,因为两个变量的值(数组)指向同一内存内容。
}
test(a);
console.log(a) // [4, 2, 3]
- 改变形参arr的指针指向时不会修改变量a。
const a = [1, 2, 3];
function test(arr) {
arr = [1, 2]; // 修改的是arr变量的指向,并不会影响a变量指向内存的内容
}
test(a);
console.log(a) // [1, 2, 3]
浅拷贝
第二层及以下的都是浅拷贝,修改第二层及以下层级内容,另一个变量还是会跟着改变。
- 扩展运算符
const obj = {
a: 1,
b: 2,
c: [1, { name: 'dyx' }]
};
const shallowCopy = {...obj};
- Object.assign
const obj = {
a: 1,
b: 2,
c: [1, { name: 'dyx' }]
};
const shallowCopy = Object.assign({}, obj);
- 自己实现
const obj = {
a: 1,
b: 2,
c: [1, { name: 'dyx' }]
};
function shallowClone(obj) {
const newObj = Object.prototype.toString.call(obj) === '[object Array]' ? [] : {};
if (typeof obj !== 'object') {
return;
} else {
for(const name in obj) {
if(obj.hasOwnProperty(name)) {
newObj[name] = obj[name];
}
}
return newObj;
}
}
const shallowCopy = shallowClone(obj);
深拷贝
所有层级都可以修改,不会影响另一个变量。
- JSON.parse
const obj = {
a: 1,
b: 2,
c: [1, { name: 'dyx' }]
};
const deepCopy = JSON.parse(JSON.stringify(obj));
- 使用递归自己实现,当value仍是对象数据格式时递归调用deepClone方法。
const obj = {
a: 1,
b: 2,
c: [1, { name: 'dyx' }]
};
function deepClone(obj) {
const newObj = Object.prototype.toString.call(obj) === '[object Array]' ? [] : {};
if (typeof obj !== 'object') {
return;
} else {
for (const name in obj) {
if (obj.hasOwnProperty(name)) {
newObj[name] = typeof obj[name] === 'object' ? deepClone(obj[name]) : obj[name];
}
}
}
return newObj;
}
const deepCopy = deepClone(obj);