闭包、深拷贝和浅拷贝

闭包

闭包(closure)指有权访问另一个函数作用域中变量的函数。

被访问的局部变量所在作用域的函数就叫闭包函数。

// 闭包:fun 这个函数作用域 访问了另外一个函数 fn 里面的局部变量num
// fn 外面的作用域也可以访问fn内部的局部变量
// 闭包的主要作用:延伸了变量的作用范围
function fn() {
    var num = 10
    // function fun() {
    //     console.log(num)
    // }
    // return fun
    return function () {
        console.log(num)
    }
}
let f = fn()
f()
fn()()

浅拷贝和深拷贝

首先,我们要知道 js 有两种数据类型,基础数据类型和引用数据类型。基础数据类型都是按值访问的,我们可以直接操作保存在变量中的实际的值。而引用数据类型如 Array 和 Object,我们不能直接操作对象的堆内存空间。引用数据类型的值都是按引用访问的,即保存在变量对象中的一个地址,指向存储在堆内存中的对象。

浅拷贝和深拷贝是指拷贝的两种情况。浅拷贝只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做浅拷贝(浅复制)。

比如:

var a = {name: 'Tom', age: 18};
var b = a; // 浅拷贝
b.name = 'Jerry';
console.log(a.name); // Jerry

可以看到,修改 b 的 name 属性后,a 的 name 属性也跟着变了。这是因为 b 只是复制了 a 的地址,并没有创建一个新的对象。

深拷贝则是对目标对象及其所有子对象进行递归复制,并返回一个新对象。这样就不会影响原对象的值了。我们把这种拷贝叫做深拷贝(深复制)。

比如:

var a = {name: 'Tom', age: 18};
var b = JSON.parse(JSON.stringify(a)); // 深拷贝
b.name = 'Jerry';
console.log(a.name); // Tom

可以看到,修改 b 的 name 属性后,a 的 name 属性没有变化。这是因为 b 是通过 JSON 方法创建了一个新的对象,并复制了 a 的所有属性。

JSON 方法并不是最完美的深拷贝方法,它有一些局限性和缺点。比如它不能处理函数、循环引用、日期等特殊情况。如果要实现更完善的深拷贝方法,可以使用一些第三方库或者自己编写递归函数来实现。

编写递归函数实现深拷贝:

function deepClone(obj) {
    // 非对象和null直接返回
    if (typeof obj !== 'object' || obj === null) {
        return obj;
    }

    // 创建新对象,考虑数组的情况
    const newObj = Array.isArray(obj) ? [] : {};

    // 遍历对象的属性,进行递归拷贝
    for (let key in obj) {
        newObj[key] = deepClone(obj[key]);
    }
    return newObj;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值