深拷贝与浅拷贝
深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在编程中常用的概念,它们指的是复制对象或数组时的不同方式。让我们来详细解释它们,并列举一些例子:
浅拷贝(Shallow Copy):
在浅拷贝中,只复制对象或数组的引用,而不是对象或数组本身的内容。因此,原始对象和复制后的对象共享相同的引用,如果修改了复制后的对象,那么原始对象也会受到影响。
示例:
// 浅拷贝对象
const originalObj = { name: 'John', age: 30 };
const copiedObj = Object.assign({}, originalObj);
// 修改复制后的对象
copiedObj.age = 40;
// 原始对象也受到了影响
console.log(originalObj.age); // 输出: 40
深拷贝(Deep Copy):
在深拷贝中,复制对象或数组的内容以及所有嵌套对象或数组的内容。这样,原始对象和复制后的对象是完全独立的,对复制后的对象的修改不会影响到原始对象。
示例:
// 深拷贝对象
const originalObj = { name: 'John', age: 30 };
const copiedObj = JSON.parse(JSON.stringify(originalObj));
// 修改复制后的对象
copiedObj.age = 40;
// 原始对象不受影响
console.log(originalObj.age); // 输出: 30
深拷贝与浅拷贝的其他例子:
- 浅拷贝:
Object.assign()
- 扩展运算符
{...obj}
- 数组的
slice()
、concat()
- 深拷贝:
- 递归复制对象或数组的每个属性
JSON.parse(JSON.stringify(obj))
(不适用于包含函数、RegExp、Date等特殊类型的对象)- 使用第三方库如
lodash
的_.cloneDeep()
方法
总之,浅拷贝只复制对象的第一层属性,而深拷贝会递归复制对象的所有属性,包括嵌套的对象或数组。在选择使用哪种拷贝方式时,需要根据具体情况来决定。
嵌套回调
// 第一个异步操作
function asyncOperation1(callback) {
setTimeout(function() {
console.log('异步操作1完成');
callback();
}, 1000);
}
// 第二个异步操作
function asyncOperation2(callback) {
setTimeout(function() {
console.log('异步操作2完成');
callback();
}, 500);
}
// 嵌套回调函数
asyncOperation1(function() {
console.log('开始执行嵌套回调');
asyncOperation2(function() {
console.log('嵌套回调执行完毕');
});
});
console.log('主线程继续执行');
执行解释(一步一步来)
执行顺序解释:
- 首先,调用
asyncOperation1
函数,它会启动一个定时器,1秒后执行回调函数。- 紧接着,调用
asyncOperation2
函数,它会启动一个定时器,0.5秒后执行回调函数。- 在异步操作1的回调函数中,输出"开始执行嵌套回调"。
- 在异步操作2的回调函数中,输出"嵌套回调执行完毕"。
- 最后,输出"主线程继续执行"。
因为异步操作是非阻塞的,所以在执行异步操作的同时,主线程会继续往下执行。当异步操作完成后,会调用相应的回调函数进行处理。在嵌套回调的情况下,内层回调函数的执行必须等到外层回调函数执行完毕后才能执行。