ES6中let的实现方式 -- 优雅而又花式闭包处理

接上文 https://blog.csdn.net/u012312705/article/details/81749777 (有关闭包的经典问题)

想要处理不想要发生的闭包,最简单的方式就是let啦

以setTimeout形成的闭包为例

for(let i = 0 ; i < 10 ; i++){
    setTimeout(()=>{
        console.log(i); // 0 - 9
        console.log(this.i); // undefined
    });
} 

如果是用的var i,那么很明显会输出20个10,但是用let 就会输出0 - 9和undefined了,

这是因为let会形成一个块级作用域(作用死域),且不会存在变量提升,而setTimeout的this永远绑定window,所以this里是找不到作为全局变量的i的。

块级作用域类似于c语言以及java里的作用域的行使方式一样,会保留i的状态,所以十次调用setTimeout都会展示i的变化

那么若是想要实现let,就是要用各种神奇的方式,把i的状态全都保存下来噢


第二种方式

try-catch

for(var i = 0 ; i < 10 ; i++){
    try {
        throw i;
    } catch (e) {
        setTimeout(()=>{
            console.log(e)
        })
    }
} 

在这里try-catch伪造的块级作用域存在于catch里,其中e是一个有着类似于块级作用域变量的特性的独立变量,他不是i,所以能够保留下i的状态的变化。


第三种方式

自执行函数,函数

for(var i = 0 ; i < 10 ; i++){
    (function(i){
        setTimeout(()=>{
            console.log(i);
        });
    })(i);
}

for(var i = 0 ; i < 10 ; i++){
    function a(i){
        setTimeout(()=>{
            console.log(i);
        })
    }
    a(i);
}

用传递参数的方式保留i的状态


第四种方式

map,forEach

来自ES6的对数组的方法

for(var i = 0 ; i < 10 ; i++){
    [i].map((i)=>{
        setTimeout(()=>{
            console.log(i);
        })
    });
    [i].forEach((i) => {
        setTimeout(()=>{
            console.log(i);
        })
    });
}

这里是用数组保存了i的状态


不知道还有没有其他办法,但是这四种,实在是足够花式了,一般来说一个let就可以搞定啦~,当然不要忘记let的无法被变量提升的效果噢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值