前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >JavaScript 中的闭包

JavaScript 中的闭包

作者头像
零式的天空
发布于 2022-03-02 12:31:21
发布于 2022-03-02 12:31:21
69800
代码可运行
举报
文章被收录于专栏:零域Blog零域Blog
运行总次数:0
代码可运行
  • content {:toc}

本文为慕课网 JavaScript深入浅出 JavaScript 中的闭包笔记。

闭包的例子

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function outer() {
    var localVal = 30;
    return localVal;
}

console.log(outer()); //30

function outer2() {
    var localVal = 30;
    return function() {
        return localVal;
    };
}

var func = outer2();
console.log(func()); //30

对于第一个普通的函数,在执行过之后,它的局部变量就可以被释放。

对于第二个函数,localVal 是不能被释放的。因为调用 outer2() 后,返回的是匿名函数,匿名函数可以访问外部的 outer2() 中的局部变量,并返回了这个局部变量 localVal。当 outer2() 赋值给 func 后,再次调用 func(),仍能访问到局部变量 localVal。这种情况就是闭包。


应用

所谓闭包就是:子函数可以使用父函数中的局部变量。


常见错误之循环闭包

比如我们想循环绑定点击事件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
document.body.innerHTML = "<div id=div1>aaa</div><div id=div2>bbb</div><div id=div3>ccc</div>";
for (var i = 1; i < 4; i++) {
    document.getElementById('div' + i).
    addEventListener('click', function() {
        alert(i); // all are 4!
    });
}

上面的代码,我们点击任何一个 div,弹出的都是 4

这是因为,for 循环中的 i 是一个全局变量。这里内函数的点击事件,访问到的是循环后的 i 值,所以是 4

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
document.body.innerHTML = "<div id=div1>aaa</div><div id=div2>bbb</div><div id=div3>ccc</div>";
for (var i = 1; i < 4; i++) {
    ! function(i) {
        document.getElementById('div' + i).
        addEventListener('click', function() {
            alert(i); // 1, 2, 3
        });
    }(i);
}

这里使用了立即执行函数,并给匿名函数赋值 i,这样点击事件每一次就会访问到相应的 i。


封装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(function() {
    var _userId = 9527;
    var _typeId = "item";
    var exp = {};

    function converter(userId) {
        return +userId;
    }

    exp.getUserId = function() {
        return converter(_userId);
    };

    exp.getTypeId = function() {
        return _typeId;
    };

    window.a = exp;
})();

console.log(a.getUserId()); //9527
console.log(a.getTypeId()); //item

console.log(a._userId); //undefined
console.log(a._typeId); //undefined
console.log(converter); //Uncaught ReferenceError: converter is not defined

上面的代码通过闭包实现了一个封装。


总结

  • 在计算机科学中,闭包(也称词法闭包或函数闭包)是指一个函数或函数的引用,与一个引用环境绑定在一起。这个引用环境是一个存储该函数每个非局部变量(也叫自由变量)的表。
  • 闭包,不同于一般的函数,它允许一个函数在立即词法作用域外调用时,仍可访问非本地变量。

from 维基百科

  • 闭包的优点
    • 灵活和方便
    • 封装
  • 缺点
    • 空间浪费
    • 内存泄露
    • 性能消耗
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 闭包的例子
  • 应用
  • 常见错误之循环闭包
  • 封装
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文