11月
11日

学习JavaScript闭包笔记

类归于: 做东西 Hbomb 写于 16:03

之前都没有系统学习过闭包,对于闭包的概念也比较迷糊。今天搜了下关于闭包的资料和文档,有的说的很复杂,也许是翻译的问题吧。之后还是找的了一个比较简单的笔记性说明文档来自于never-online的一篇不错的文章:在Javascript中,什么是闭包(Closure)?

这篇文章的英文原创来自于:http://blog.morrisjohns.com/javascript_closures_for_dummies

于是我对照了原著看了下,更加深了印象,感觉闭包使用的恰当,效果很好的。

首先,闭包是什么?

  • a closure is the local variables for a function - kept alive after the function has returned, or
  • a closure is a stack-frame which is not deallocated when the function returns.
    (as if a ’stack-frame’ were malloc’ed instead of being on the stack!)
  1. 作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
  2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。


function sayHello(name) {
var text = 'Hello ' + name;
var sayAlert = function() { alert(text); }
sayAlert();
}

以上的代码就表示了闭包的最基本的形式,在一个函数里面包含一个内部函数。
闭包有一个好处,就是变量作用域控制,和内部函数作用域的控制,是外界没法访问内部函数,使代码安全性提高,形成代码的单元。
其实,我还是看到never-online的另一篇
eval解闭包
里面说道:

[edit] Syntax
eval(string [, object])

[edit] Parameters
string
A string representing a JavaScript expression, statement, or sequence of statements. The expression can include variables and properties of existing objects.
object
Non-standard
An optional argument; if specified, the evaluation is restricted to the context of the specified object.

呵呵,这么看来对于JavaScript私有的概念十分的弱了。eval是一个危险的方法,虽然灵活,但是得小心的用,就像goto语句一样有争议了。

最后总结下:
Final points:

* Whenever you use function inside another function, a closure is used.
每当你在一个函数里有另一个函数,表示已使用了闭包。
* Whenever you use eval() inside a function, a closure is used. The text you eval can reference local variables of the function, and within eval you can even create new local variables by using eval(’var foo = …
每当你使用函数里使用eval(),也表示使用了闭包。你执行的文本能够应用这个函数里的局部变量,甚至在eval里创建新的这个函数的局部变量,像这样:eval(’var foo =…
* When you use Function() inside a function, it does not create a closure. (The new function cannot reference the local variables of the function calling Function()).
当你在一个函数里使用Function(),并不会创建一个闭包。(当调用这个新建的函数并不能引用函数的局部变量)
* A closure in JavaScript is like keeping a copy of the all the local variables, just as they were when a function exited.
当一个函数退出时,在JavaScript里一个闭包就像是保持了所有局部变量的拷贝。
——————————————————————–
下面偷懒了,不翻译了,发现翻译措辞很痛苦,虽然看懂了,却不知道咋么表达好,大家一起看e文吧,或者有哪个达人帮忙翻译下。
* It is probably best to think that a closure is always created just on entry to a function, and the local variables are added to that closure.

* A new set of local variables is kept every time a function with a closure is called (Given that the function contains a function declaration inside it, and a reference to that inside function is either returned or an external reference is kept for it in some way).

* Two functions might look like they have the same source text, but have completely different behaviour because of their ‘hidden’ closure. I don’t think JavaScript code can actually find out if a function reference has a closure or not.

* If you are trying to do any dynamic source code modifications ( for example: myFunction = Function(myFunction.toString().replace(/Hello/,’Hola’)); ), it won’t work if myFunction is a closure (Of course, you would never even think of doing source code string substitution at runtime, but…).

* It is possible to get function declarations within function declarations within functions - and you can get closures at more than one level.

* I think normally a closure is the term for both the function along with the variables that are captured. Note that I do not use that definition in this article!

* I suspect that closures in JavaScript differ from those normally found in functional languages.