JavaScript之闭包(closure)

“JavaScript中的函数运行在它们被定义的做用域里,而不是它们被执行的做用域里。”

一些关于闭包的定义:javascript

  1. 闭包是指有权访问另外一个函数做用域中变量的函数 --《JS高级程序设计第三版》 p178
  2. 函数对象能够经过做用域链相关联起来,函数体内部的变量均可以保存在函数做用域内,这种特性称为 ‘闭包’ 。 --《JS权威指南》 p183
  3. 内部函数能够访问定义它们的外部函数的参数和变量(除了thisarguments)。 --《JS语言精粹》 p36

要理解js中的闭包必须清楚另外一个概念scope。JS中采用”链式做用域”结构(chain scope),子对象能够一级一级地向上寻找全部父对象的变量。html

JS的scope基于function,而function是能够做为普通对象处处传递的,常常会有一个function内部定义的函数放到其余地方使用的状况。所谓的闭包就是当函数在其余地方使用的时候能保存下函数所须要的运行环境,也便是函数能保存下函数诞生时的环境。java

var a=1

var b=function(){
    return a+1 
}

b() // => 2

这个案例中,变量a是一个依赖闭包机制所捕获的自由变量,也所以函数b能够被正常执行。(做者:项昊凡 连接:https://www.zhihu.com/question/34547104/answer/59560912)闭包

另外一种说法:函数

代码指令执行时候,会处于必定的环境,单纯将代码保存下来,仍是不够的,须要将代码所处的环境也保存下来。闭包实际上是,将代码跟代码所处于的环境作为一个总体来看待。周围的环境,表现为代码所使用的数据。在有些语言中,这个概念叫代码块(block),匿名函数(lambda)等等。this

数据跟代码再也不人为割裂开来,统一块儿来看待。闭包就会是很天然的概念。数据能够传递,从一个地方传递到另外一个地方,而且之后再使用。闭包从某个角度来讲,也是数据,固然也能够传递,从一个函数传递到另外一个函数,也能够保持下来,之后再调用。由于将环境也保持下来了,之后调用的时候,就还原当时的状况,延迟执行,就很容易,很天然地实现了。而延迟执行有什么做用?就是另外一个话题了。(做者:黄兢成 连接:https://www.zhihu.com/question/24084277/answer/28476841)spa

再一个Javascript闭包的例子:.net

function A(x){
    return function B(y) {
         return x*y
    }
}

首先,变量x对于B(y)来讲是一个外部自由变量,B()调用时须要x;其次,B的外部环境A包含x;再次,JS容许B访问A的变量。设计

转一道有意思的题目:code

function fun(n,o) {
 console.log(o)
 return {
  fun:function(m){
   return fun(m,n);
  }
 };
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,?
//问:三行a,b,c的输出分别是什么?

答案请查阅原文:http://www.jb51.net/article/75450.htm

最后贴上阮一峰老师关于闭包的介绍http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
相关文章
相关标签/搜索