How do JavaScript closures work?
|
Like the old Albert Einstein said:
Well, I tried to explain JavaScript closures to a 27-year-old friend and completely failed. How would you explain it to someone with a knowledge of the concepts which make up closures (for example, functions, variables and the like), but does not understand closures themselves? I have seen the Scheme example given on Stack Overflow, and it did not help.
|
|||||||||||||||||||||
|
JavaScript Closures for Dummies
Closures Are Not MagicThis page explains closures so that a programmer can understand them — using working JavaScript code. It is not for gurus or functional programmers. Closures are not hard to understand once the core concept is grokked. However, they are impossible to understand by reading any academic papers or academically oriented information about them! This article is intended for programmers with some programming experience in a mainstream language, and who can read the following JavaScript function:
An Example of a ClosureTwo one sentence summaries:
The following code returns a reference to a function:
Most JavaScript programmers will understand how a reference to a function is returned to a variable ( There is a critical difference between a C pointer to a function and a JavaScript reference to a function. In JavaScript, you can think of a function reference variable as having both a pointer to a function as well as a hidden pointer to a closure. The above code has a closure because the anonymous function In C, and most other common languages after a function returns, all the local variables are no longer accessible because the stack-frame is destroyed. In JavaScript, if you declare a function within another function, then the local variables can remain accessible after returning from the function you called. This is demonstrated above, because we call the function
Looking at the output of The magic is that in JavaScript a function reference also has a secret reference to the closure it was created in — similar to how delegates are a method pointer plus a secret reference to an object. More examplesFor some reason, closures seem really hard to understand when you read about them, but when you see some examples you can click to how they work (it took me a while). I recommend working through the examples carefully until you understand how they work. If you start using closures without fully understanding how they work, you would soon create some very weird bugs! Example 3This example shows that the local variables are not copied — they are kept by reference. It is kind of like keeping a stack-frame in memory when the outer function exits!
Example 4All three global functions have a common reference to the same closure because they are all declared within a single call to
The three functions have shared access to the same closure — the local variables of Note that in the above example, if you call Example 5This one is a real gotcha for many people, so you need to understand it. Be very careful if you are defining a function within a loop: the local variables from the closure do not act as you might first think.
The line
Note that when you run the example, Example 6This example shows that the closure contains any local variables that were declared inside the outer function before it exited. Note that the variable
Tricky: note also that the Example 7This final example shows that each call creates a separate closure for the local variables. There is nota single closure per function declaration. There is a closure for each call to a function.
SummaryIf everything seems completely unclear then the best thing to do is to play with the examples. Reading an explanation is much harder than understanding examples. My explanations of closures and stack-frames, etc. are not technically correct — they are gross simplifications intended to help understanding. Once the basic idea is grokked, you can pick up the details later. Final points:
Links
ThanksIf you have just learnt closures (here or elsewhere!), then I am interested in any feedback from you about any changes you might suggest that could make this article clearer. Send an email to morrisjohns.com (morris_closure @). Please note that I am not a guru on JavaScript — nor on closures. |
How do JavaScript closures work?的更多相关文章
- JavaScript——closures(待续)
问答原文:How do JavaScript closures work?
- JavaScript Closures 闭包
在一些编程语言中, 当我们执行完成function中的局部代码仅在函数执行期间可运行. 但是JS 事不一样的 闭包总结来说, 就是innerFunction 总是有使用outer function 的 ...
- 深入理解JavaScript系列(16):闭包(Closures)
介绍 本章我们将介绍在JavaScript里大家经常来讨论的话题 —— 闭包(closure).闭包其实大家都已经谈烂了.尽管如此,这里还是要试着从理论角度来讨论下闭包,看看ECMAScript中的闭 ...
- JavaScript:内存泄露、性能调优
1.在进行JS内存泄露检查之前,先要了解JS的内存管理: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Manageme ...
- JavaScript之闭包
JavaScript之闭包 在JavaScript中,闭包恐怕是很多人不能理解的一个概念了,甚至很多人也会把闭包和匿名函数混淆. 闭包是有权访问另一个函数作用域中的变量的函数.首先要明白的就是,闭包是 ...
- 理解和使用 JavaScript 中的回调函数
理解和使用 JavaScript 中的回调函数 标签: 回调函数指针js 2014-11-25 01:20 11506人阅读 评论(4) 收藏 举报 分类: JavaScript(4) 目录( ...
- [译]JavaScript规范-葵花宝典
[译]JavaScript规范 译自:https://github.com/airbnb/javascript 类型 原始值: 相当于传值 string number boolean null und ...
- JavaScript闭包的底层运行机制
转自:http://blog.leapoahead.com/2015/09/15/js-closure/ 我研究JavaScript闭包(closure)已经有一段时间了.我之前只是学会了如何使用它们 ...
- 什么是JavaScript闭包终极全解之一——基础概念
本文转自:http://www.cnblogs.com/richaaaard/p/4755021.html 什么是JavaScript闭包终极全解之一——基础概念 “闭包是JavaScript的一大谜 ...
随机推荐
- 测试TCP/IP配置
安装网络硬件和网络协议之后,我们一般要进行TCP/IP协议的测试工作,那么怎样测试才算是比较全面的测试呢?我们认为,全面的测试应包括局域网和互联网两个方面,因此应从局域网和互联网两个方面测试,以下是我 ...
- linux服务器出现严重故障后的原因以及解决方法
1.把系统安装光盘插入,重启机器,启动时迅速按下Del键,进入CMOS,把启动顺序改为光盘先启动,这样就启动了Linux安装程序,按F5,按提示打入Linux rescue回车,进入救援模式,接下来是 ...
- JavaScript join() 方法
http://www.w3school.com.cn/jsref/jsref_shift.asp JavaScript Array 对象 定义和用法 join() 方法用于把数组中的所有元素放入一个字 ...
- if语句,函数function
1.语句 一般分为顺序,分支和循环语句. if是分支语句 格式1:if(){} 若满足就进入花括号,若不满足就跳过 格式2:if(){}else(){}二选一.若if满足则else一定不执行,反之则 ...
- json 帮助工具
import java.lang.reflect.Type; import com.google.gson.Gson; /** * json 帮助工具 */public final class Gso ...
- jPaginate应用
分页结合bingojs需要注意两点 1.标签要放在bg-render外面 2.ajax请求参数包含一页显示多少条数据的字段,跟分页插件无关. 调用jPaginate插件的方法很简单: $('#page ...
- eclipse安卓引入库项目的正确方法
之前清单文件里theme主题老是改不成库项目里定义好的主题@style/Theme.AppCompat.Light,只能用默认主题@style/AppTheme <application and ...
- centos 6.2安装bind 9.8.2 master、slave与自动修改后更新
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dl528888.blog.51cto.com/2382721/1249311 随 ...
- NDK编译应用程序
Android源码目录下的build/envsetup.sh文件,描述编译的命令 - m: Makes from the top of the tree. - mm: Build ...
- Hibernate 系列教程17-查询缓存
在二级缓存配置成功的基础上进行查询缓存配置 Product public class Product { private Long id; private String name; Product.h ...