JavaScript闭包

xiaoxiao2021-02-28  101

1. 引言

如果您了解JavaScript函数和模块的概念,学习闭包对您来说应该不是一个大问题。如果你刚刚接触JavaScript,没有了解过这两个概念,那也没问题。闭包属于高级JavaScript概念的类别,但相信我,如果你知道和了解内部函数的工作原理,理解闭包将是小菜一碟。

2.内部函数

内部函数从根本上说是“函数内的函数”。 JavaScript支持嵌套函数,这意味着您可以在函数内创建一个或多个函数。内部函数可能再次包含内部函数,这种嵌套可以更深入。让我们看一个简单的例子。

function innerOuterDemo(){ console.log("The outer function"); function innerFunction(){ console.log("The inner function"); } return innerFunction; }

函数innerOuterDemo包含一个名为innerFunction的内部函数,它将“内部函数”写入控制台。 对innerOuterDemo的调用将会将“外部函数”写入控制台并返回函数innerFunction。

var doSomething = innerOuterDemo(); // Logs "The outer function" and returns innerFunction doSomething(); // Logs "The inner function"

十分简单且直截了当。但是请记住,一旦函数完成执行并返回,它就不再起作用了。 这表示当innerOuterDemo被执行并返回innerFunction时,innerOuterDemo不再在作用范围内。

现在我们已经介绍了函数嵌套和作用范围的基础知识,先让我们跳出闭包。 思考下面的例子:

function foodAndMore(){ var myFood = "Pizza and Pasta"; function getMyFood(){ return myFood; } return getMyFood; } var foodILove = foodAndMore(); console.log("I love " + foodILove());

和第一个例子非常类似,除了变量myFood。 变量myFood属于外部函数foodAndMore,但却在内部函数getMyFood内部作为return语句的部分来使用。 调用foodAndMore函数将返回的getMyFood函数分配给变量foodILove。 当您运行上述代码段时,控制台将会出现“我喜欢披萨和面食“。

这里有什么特别之处呢? 之前我说过,当函数完成执行时它就不再起作用了? 但是如果是这样,在执行完函数foodAndMore并返回时,不应该包含变量myFood。但是您在控制台中看到“我喜欢披萨和面食”的输出,那肯定不是这样的,那到底是什么样的呢?这就要看下面的介绍了。

3.闭包

闭包是内部函数访问外部函数变量的一个桥梁。 换句话说,闭包是一个可以访问外部函数的变量内部函数。 回过头来,让我们继续看上一个关于食物的例子。 正如我们已经观察到的,内部函数getMyFood可以访问外部函数的变量myFood,即使外部函数已经执行完毕。 所以函数getMyFood和变量myFood的组合就是一个闭包的例子。 我们可以随时通过引用变量(例如foodILove)来调用getMyFood函数并获取“Pizza and Pasta”的myFood变量的值。

在JavaScript中,内部函数不仅可以访问外部函数的变量,还可以访问它们的参数。 下一个例子将证明这一点。

function getMultiplier(multiplyBy){ function multiply(num){ return multiplyBy * num; } return multiply; } var multiplyByTwo = getMultiplier(2); var multiplyByTen = getMultiplier(10); var twoIntoFive = multiplyByTwo(5); // 10 var tenIntoSix = multiplyByTen(6); // 60

所以内函数multiply可以访问外函数的参数multiplyBy。 外部函数getMultiplier返回一个可以用作乘数函数的函数。 我们正在创建两个函数multiplyByTwo和multiplyByTen。 在调用这两个函数时,JavaScript运行时会记住执行环境(getMultiplier函数的参数),并执行数字之间的乘法。

闭包在JavaScript和JavaScript的库和框架中广泛使用。 当您将内联函数写入事件处理程序或回调函数时,简单的例子就是事件处理和AJAX调用。 这些内联函数可以访问main(外部)函数的变量和参数。

以下是jQuery中按钮单击事件处理函数(闭包)的示例。 即使外部函数未执行,该函数也可以访问计数变量及其状态。

$(function(){ var count = 1; $("#counterBtn").Click(function(){ alert("Your click count is: " + count++); }); });

闭包也可用于定义可以访问JavaScript模块模式中的私有函数和变量的公共函数。 下面给出一个简单的例子。

var mathUtility = (function(){ var count = 1; function increment(number){ return number + count; } function decrement(number){ return number - count; } return { nextOf: increment, previousOf: decrement }; }()); var numberAfterFive = mathUtility.nextOf(5); // 6 var numberBeforeTen = mathUtility.previousOf(10); // 9

我们创建了一个包含两个私有函数increment和decrement的模块mathUtility。 两个私有函数都可以访问外部匿名函数中的count变量,从而形成闭包。 return返回的对象,实际上是一个名为mathUtility的模块,它包含两个公共函数nextOf和previousOf,可以用于查找任何给定数字的下一个或前一个数字。以上就是对闭包的讲述。

转载请注明原文地址: https://www.6miu.com/read-84004.html

最新回复(0)