作用域闭包

闭包有3个特性:
①函数嵌套函数
②函数内部可以引用函数外部的参数和变量
③参数和变量不会被垃圾回收机制回收

function outter(){
    var name='dov'
    function innter(){
        return name;
    }
    return innter
}
var innter=outter();
console.log(innter())

outter()返回了一个具名函数inner,这个函数在outter()作用域内部,所以它可以获取outter()作用域下变量name的值,将这个值作为返回值赋给全局作用域下的变量innter,实现了在全局变量下获取到局部变量中的变量的值。

function fn(){
    var num=3
    return function(){
        var n=0;
        console.log(++n);
        console.log(++num);
    }
}
var fn1=fn();
fn1();  // 1 4
fn1();  // 1 5

一般情况下,在函数fn执行完后,就应该连同它里面的变量一同被销毁,但是在这个例子中,匿名函数作为fn的返回值被赋值给了fn1,这时候相当于fn1=function(){var n = 0 … },并且匿名函数内部引用着fn里的变量num,所以变量num无法被销毁,而变量n是每次被调用时新创建的,所以每次fn1执行完后它就把属于自己的变量连同自己一起销毁,于是乎最后就剩下孤零零的num,于是这里就产生了内存消耗的问题

for(var i=1;i<=5;i++){
    setTimeout(function timer() {
        console.log(i)  // 6 6 6 6 6 
    }, 1000);   
}

延时的回调函数会在循环结束时才执行。当定时器运行时即使每个迭代中执行的是 setTimeout(。。。 1000); 所有的回调函数依然是在循环结束后才会被执行,因此会每次输出一个6出来。

for(var i=1;i<=5;i++){
    (function(j){
        setTimeout(function timer() {
            console.log(j)  // 1 2 3 4 5
        }, 1000);
    })(i)
}

我们每次迭代时都创建一个新的作用域。
改造成下面的方式,let声明可以用来劫持快作用域

for(let i=1;i<=5;i++){ 
    setTimeout(function timer() {
        console.log(i)  // 1 2 3 4 5
    }, 1000);
}

for循环头部的let声明会有一个特殊的行为,这个行为支出变量在循环过程中不止被声明一次,每次迭代都会声明。随后的每个迭代都会使用上一个迭代结束时的值来初始化这个变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值