每日前端夜话,陪你聊前端。
每天晚上18:00准时推送。
正文共:1143 字
预计阅读时间:5 分钟
翻译:疯狂的技术宅
来源:freecodecamp
闭包是函数创建时作用域内所有变量的集合。要使用闭包,需要在另一个函数中创建一个函数,这种函数被称为嵌套函数。内部函数可以访问外部函数作用域中的变量(依靠闭包可以访问外部函数作用域),即使在返回外部函数之后也是如此。每次创建嵌套函数时都会创建闭包。
在继续了解闭包之前,首先了解一下JavaScript中的作用域链。
通常,有两种类型的作用域:
全局作用域
局部作用域
在JavaScript中,函数内部的变量在外部是不可见的。但是在块内的变量(if 或 while 之类)是可见的。
因此,JavaScript有函数作用域。没有块作用域。
1var a = 10;
2function app(){
3 var b = 2;
4 console.log(a); // 10
5 console.log(b); // 2
6}
7console.log(b); // ReferenceError: b is not defined
8app();
正像我们已知的那样,a 是一个全局变量并且 b 是一个局部变量,它是app函数独有的。
我们无法从局部作用域之外获取局部变量的值。
1var a = 10;
2function app(){
3 var b = 2;
4 var d = 3;
5 function add(){
6 var c = a + b;
7 }
8 return add;
9}
10var x = app();
11console.dir(x);
在这里app是父函数,add函数是子函数。
代码中没有用 console.log 而是用了console.dir 来输出指定JavaScript对象的所有属性,这有助于开发人员获取对象的属性
变量 x 被分配给app函数,app函数返回add函数。因此我们可以看到add函数的所有对象属性。
如果在浏览器中查看控制台,可以在Scopes数组中看到Closure对象。
由于内部函数add访问外部函数变量b 和 d,因此这2个变量将被添加到Closure对象中以供引用。
让我们看看下一个例子:
1var a = 10;
2var startFunc;
3function app(){
4 var b = 2;
5 function add(){
6 var c = a + b;
7 console.log(c);
8 }
9 startFunc = add();
10}
11app(); // 调用app函数
12startFunc; // 上面调用的app函数会将add函数赋值给startFunc并输出c的值
一个名为 startFunc 的全局函数被分配给add函数,该函数是 app 函数的子函数。
这只有在调用 app 函数后才有可能,否则 startFunc 将作为全局变量而不被分配任何值
很多人在编码时会用到闭包,但是不明白用它的原因。 JavaScript没有像其他面向对象语言一样的访问修饰符,例如 private,public,protected。不过我们可以利用函数来保护命名空间免受外部代码使用的影响。
特别是在函数中,立即执行函数表达式(IIFE)是在声明之后会立即执行的函数表达式。在声明函数之后,你不需要去调用该函数。
IIFE的语法定义是:
1(function(){
2 //函数内部的变量和作用域
3})();
举个例子:
1var studnetEnrollment = (function () {
2 //私有变量,任何人都无法改变
3 //除了下面声明的函数
4 var count = 0;
5 var prefix = "S";
6 // 返回一个命名函数表达式
7 function innerFunc() {
8 count = count + 1;
9 return prefix + count;
10 };
11 return innerFunc;
12})();
13var x = studnetEnrollment(); // S1
14console.log(x);
15var y = studnetEnrollment(); // S2
16console.log(y);
count和prefix是两个私有变量,任何人都无法进行更改,只能访问内部函数(即代码中的innerFunc)。只有名为闭包的功能才能对此进行访问。
第一次调用studentEnrollment函数时,函数内的count变量由innerFunc函数递增加1。
第二次,增加上一个计数值,即 1 增加到 2
Closure功能可以实现这些功能。
闭包是外部函数中的变量集合,它提供对内部函数作用域的访问以保护全局命名空间。
闭包使开发人员能够编写像面向对象语言那样的干净代码,这些代码不会混淆全局和局部变量的名称。
编码快乐…… !!!!!
原文:https://medium.freecodecamp.org/a-basic-guide-to-closures-in-javascript-9fc8b7e3463e
如果你觉得这篇文章对你有帮助,请点击右下角的 “🌸好看” 并分享给小伙伴们↘️↘️↘️🙏🏼
下面夹杂一些私货:也许你和高薪之间只差这一张图
2019年京程一灯课程体系上新,这是我们第一次将全部课程列表对外开放。
愿你有个好前程,愿你月薪30K。我们是认真的 !
在公众号内回复“体系”查看高清大图
在公众号内回复“体系”查看高清大图
长按二维码,加大鹏老师微信好友
拉你加入技术交流群
唠一唠怎样才能拿高薪
往期精选文章 |
---|
CSS粘性定位是怎样工作的 |
CSS Flexbox 可视化手册 |
2018年JavaScript状态调查 |
12个令人惊奇的CSS实验项目 |
使用虚拟dom和JavaScript构建完全响应式的UI框架 |
V8引擎内部机制及优化代码的5个技巧 |
小手一抖,资料全有。长按二维码关注前端先锋,阅读更多技术文章和业界动态。