继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Javascript匿名函数与闭包之间的关系

五月君
关注TA
已关注
手记 120
粉丝 7785
获赞 2338

匿名函数就是没有名字的函数,闭包是可访问一个函数作用域里变量的函数,由于闭包作用域返回的局部变量资源不会被立刻销毁回收,所以可能会占用更多的内存。过度使用闭包会导致性能下降,建议在非常有必要的时候才使用闭包。

匿名函数的自我执行
(function(num){
        return num;
    })(1) //1
函数里放一个匿名函数将会产生闭包
  1. 使用局部变量实现累加功能。
  2. 定义函数test1,返回一个匿名函数形成一个闭包
  3. 将tes1赋给test2,此时test2会初始化变量a,值为test1返回的匿名函数
  4. 执行test2()
{
    function test1(){
        var a = 1;

        return function(){
            // a++;
            // return a;
            // 或以下写法
            return ++a;
        }
    }

    var test2 = test1();

    console.log(test2()); // 2
    console.log(test2()); // 3
    console.log(test2()); // 4

    //不能这样写,这样外层函数每次也会执行,从而age每次都会初始化
    console.log(test1()()); // 2
    console.log(test1()()); // 2
    console.log(test1()()); // 2
}
闭包中使用this对象将会导致的一些问题

在闭包中使用this对象也可能会导致一些问题,this对象是在运行时基于函数的执行环境绑定的,如果this在全局范围就是window,如果在对象内部就指向这个对象。而闭包却在运行时指向window的,因为闭包并不属于这个对象的属性或方法

返回object

var box={
    getThis:function(){
        return this;
    }
}

console.log(box.getThis()); // { getThis: [Function: getThis] }

闭包中的this将返回全局对象,浏览器中window对象,node中global对象,可以使用对象冒充或者赋值来解决闭包中this全局对象问题。

var box={
    user: 'zs',
    getThis:function(){
        return function(){
            return this;   
        };
    }
}

console.log(box.getThis()());

对象冒充

var box={
    user: 'zs',
    getThis:function(){
        return function(){
            return this;   
        };
    }
}

console.log(box.getThis().call(box)); // { user: 'zs', getThis: [Function: getThis] }

赋值

var box={
    user: 'zs',
    getThis:function(){
        var that = this; // 此时的this指的是box对象
        return function(){
            return that.user;   
        };
    }
}

console.log(box.getThis()()); 
一个例子看懂循环和闭包之间的关系

下例,循环中的每个迭代器在运行时都会给自己捕获一个i的副本,但是根据作用域的工作原理,尽管循环中的五个函数分别是在各个迭代器中分别定义的,但是它们都会被封闭在一个共享的全剧作用域中,实际上只有一个i,结果每次都会输出6

for(var i=1; i <= 5; i++){
    setTimeout(function(){
        console.log(i);
    })
}

解决上面的问题,在每个循环迭代中都需要一个闭包作用域,下面示例,循环中的每个迭代器都会生成一个新的作用域。

for(var i=1; i <= 5; i++){
    (function(j){
        setTimeout(function(){
            console.log(j);
        })
    })(i)
}

也可以使用let解决,let声明,可以用来劫持块作用域,并且在这个块作用域中生明一个变量。

for(let i=1; i <= 5; i++){
    setTimeout(function(){
        console.log(i);
    })
}

github地址 Javascript匿名函数与闭包之间的关系

打开App,阅读手记
2人推荐
发表评论
随时随地看视频慕课网APP