JavaScript中的闭包
介绍
在大多数常用语言中,函数返回后,所有局部变量不再可访问,因为堆栈帧已被销毁。牢记这一点,闭包可以被看作是当函数返回时不会释放的栈帧。
为什么使用闭包
我有很多人问我为什么要关闭。我会尽力解释。
我遇到过闭包的场景是使用Tabular Controls,File Objects等。使用闭包我可以存储我可以用于其他客户端功能的页面索引,行计数等。通过FSO,我可以保存文件路径,计数等以备后用。它不仅适用于复杂的客户端控件。想想你的页面有很多控件并且你正在执行客户端验证的场景。每次你通过一个控制器
document.getElementById("controlname")
正在搜索整个页面控制树。这可以通过使用闭包并保存控件一次来避免。可重用性是关闭的关键优势。希望我已经说服了几个人至少知道关闭。
使用代码
看看下面的功能:
现在我们以下面的方式调用函数:
var say2 = sayHello("Sachin");
say2();
该函数sayHello()返回一个指向该函数的指针sayAlert()。
这里,当你在另一个函数中声明一个函数时,局部变量可以在从你调用的函数返回后保持可访问。这在上面已经说明了。我们say2()
在从我们返回之后调用函数sayHello()。
请注意,我们调用的代码引用了变量text,该变量是函数的局部变量sayHello()。
考虑下面的功能:
这三个函数gAlertNumber(),gIncreaseNumber()并且gSetNumber(x)可以共享同一个闭包 - setupSomeGlobals()三个函数定义时的局部变量。
这可以通过一个接一个地调用函数来检查。
尝试下面的顺序:
如果我们setupSomeGlobals()再次调用,则会创建一个新的闭包(堆栈帧!)。老gAlertNumber,gIncreaseNumber,gSetNumber
变量被改写新的具有新功能关闭。
概要
JavaScript中的闭包就像保留所有局部变量的副本一样,就像退出函数时一样。
可能最好认为闭包总是在函数的入口处创建,并且局部变量被添加到闭包中。
每次调用具有闭包的函数时都会保留一组新的局部变量(假设函数内部包含函数声明,并且返回该函数的引用或者以某种方式为其保留外部引用)。