带你轻松了解JavaScript闭包

发展至2020年,前端开发的运用也越加的广,包括了游戏、网页、⼩程序、APP、跨端开发以及新技术应用方面等各个方面。

企业对优质前端开发人才的需求量更是日渐增长!想要掌握好过硬的前端技术点,多多少少都绕不开JavaScript。

今天要讲的知识点,就是JavaScript闭包!

闭包可以让JavaScript程序员编写更好的代码。创意满满、印象深刻又简洁。

我们经常在JavaScript中使用闭包,无论你的JavaScript经验多少,总会遇到它们。

也许,闭包可能看起来很复杂,但阅读完这篇文章后,就会容易理解很多。

什么是闭包?

关于闭包的产生

闭包的构成

助于理解的案例

什么是闭包?

闭包是一个内部函数,可以访问外部(封闭)函数的变量范围链。

闭包有三个范围链:它可以访问自己的范围(在大括号之间定义的变量),它可以访问外部函数的变量,并且它可以访问全局变量。

内部函数不仅可以访问外部函数的变量,还可以访问外部函数的参数。需要注意的是:即使可以直接调用外部函数的参数,内部函数仍然不能调用外部函数的参数对象。

闭包的产生

Javascript的运行在运行过程中有变量具有局部作用域和全局作用域的区分

局部作用域内可以访问全局作用域的变量 反之不可

当局部作用域变量被保存到外部 能够被访问到则闭包形成

闭包的形成和Javascript的作用域以及作用域链(Chain scope)密不可分,闭包的形成其实就是作用域链没有被释放,因此会造成内存泄露。

闭包的构成

从名字上来看闭包肯定是闭合包裹的一个东西,其实就是用一个函数来包裹需要return给外部的内容(可以是变量、函数等任何你想保存的东西),利用的就是函数的作用域和作用域链。

通过在另一个函数中添加一个函数来创建一个闭包。

JavaScript闭包的基本示例:

闭包在Node.js中广泛使用; 它们是Node.js的异步,非阻塞架构中的主轴。闭包也经常用在jQuery和JavaScript代码中。

闭包的经典jQuery示例:

闭包规则和副作用

1、闭包可以访问外部函数的变量:

闭包最显著的特征就是闭包可以访问到外部函数变量,即使外部函数变量已经被返回。JavaScript中的函数执行都是相同的作用域链(函数可以从内往外访问)。因此,您可以稍后在程序中调用内部函数。

此示例演示:function celebrityName (firstName) { var nameIntro = "This celebrity is "; // 这个内部函数可以访问外部函数的变量,包括参数 function lastName (theLastName) { return nameIntro + firstName + " " + theLastName; } return lastName; } var mjName = celebrityName ("Michael"); // 此时celebrityName外部函数返回。//闭包(lastName)在外部函数返回后调用 //然而,闭包仍然可以访问到外部函数的变量和参数 mjName ("Jackson"); // 这个名人是迈克尔·杰克逊

2、闭包引用外部函数的变量存储,不存储实际值。

当外部函数的变量的值在调用闭包之前改变时,闭包变得更有趣。

这个强大的功能可以创造性的利用,看下面代码:

function celebrityID () { var celebrityID = 999; //用内部函数返回一个对象 //所有的内部函数可以访问外部函数的变量 return { getID: function () { //这个内部函数将返回更新celebrityID变量 return celebrityID; //它将返回celebrityID的当前值,即使changeTheID函数更改 },setID: function (theNewID) { //这个内部函数会随时改变外部函数的变量 celebrityID = theNewID; } } } var mjID = celebrityID (); // 此时,该celebrityID外部函数返回。mjID.getID(); // 999 mjID.setID(567); // 改变外部函数变量 mjID.getID(); // 567

3、闭包缓存

由于闭包可以访问外部函数的变量的更新值,当用一个for循环改变外部函数的变量时,也可能导致错误。从而:// 这个例子的细节下面会说 function celebrityIDCreator (theCelebrities) { var i; var uniqueID = 100; for (i = 0; i

在前面的例子中,在调用匿名函数时,i的值为3(数组的长度,然后递增)。数字3已添加到uniqueID以为所有名人ID创建103。因此返回的数组中的每个位置都得到 id = 103,而不是预期的100,101,102。

发生这种情况的原因是,正如我们之前例子中讨论的,闭包(本例中的匿名函数)可以通过参数访问外部函数的变量,而不是一个值。

因此,正如前面的例子所示,我们可以使用闭包访问更新的变量,这个例子类似地访问i变量改变时,因为外部函数运行整个for循环并返回i的最后一个值,即103。

要解决在闭包这个副作用(错误),你可以使用一个立即调用函数表达式(IIFE):

随着JavaScript 的飞速发展,前端开发变得越来越有趣,新的库、框架层出不穷,同时,如果没有不断去提升自己的开发人员只会越来越感到心力交瘁。

所以,无论你是编程新手,还是经验丰富的开发人员,我们必须保持学习,才能跟上技术的快速变化。

想要进一步系统掌握编程的技术点,但是又找不到靠谱的视频教程,也可以留言跟我索取哦!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200110A05O8300?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券