闭包,又见闭包。。。。?

1.闭包是指有权访问另外一个函数做用域中的变量的函数。

上面这段话来自 javascript 高级程序设计 第三版 P178 。做者说闭包是一个函数,它有访问另外一个函数做用域中的变量的能力。javascript

2.函数访问它被建立时所处的上下文环境。这被称为闭包。

这段话来自 javascript 语言精粹 修订版 P38 。做者没有定义闭包为什么物,只是说函数访问它被建立时的上下文环境,这种xxx(行为?过程?能力?) 被称为闭包。前端

3.1闭包是依赖于词法做用域编写代码而产生的结果

3.2闭包就是函数可以记住并访问它的词法做用域,即便当这个函数在它的词法做用域以外执行时java

这两段话来自 You-Dont-Know-JS 做用域闭包 这一章,做者说闭包是一种结果。git


闭包的通常定义

闭包是一种抽象概念,每一个人对其理解不一样,因此有了上面的几种解释。但你们讨论的确是同一个问题。github

//step 1
function outer() {
  var a = 'hello world';
  function inner() {
    return a ;
  }
  return inner();
}
// hello world
outer();

咱们发现位于 outer 函数内的 inner 函数能够访问到另外一个函数 outer 的做用域中的变量 a 。完美的闭包,对,闭包就这么简单。哈哈哈哈哈,本文结束!!!后端


闭包的由来

其实上面那段代码并非你们真正所说的闭包,它实际上是利用了函数做用域的特色 -- 内层函数能够访问外层变量。这仅仅是闭包的一部分,闭包利用函数做用域达到了访问外层变量 a 的目的。闭包

依据定义 1,闭包能够说在代码 step1 中已经产生了。
咱们接下来看 step2:函数

//step 2
function outer() {
  a = 'hello world';
  function inner() {
      return a;
    }
  return inner();
}

var c = outer();
// hello world
c;

此次咱们执行 outer 函数, outer() 是一个函数对象,在内部只会返回 inner 函数的结果 a ,由于 inner 函数的存在,每次执行 inner 便会对变量 a 进行引用,这会致使变量 a 的引用计数为 1 ,从而垃圾回收机制没法销毁变量 a。咱们便在函数执行完毕后依然访问到了变量 a。正规的写法如 step3:设计

//step3
var c = (function() {
  var a = 'hello world';
  return {
    inner : function() {
      return a;
    }
  }
})();

// hello world
c.inner();

咱们利用自执行匿名函数把 inner 函数保存到对象 c 上,这时 c.inner 就是 inner 函数,它能够访问到 inner 函数以外的变量 a 。变量 c.inner 引用了变量 a 的值,致使变量 a 在函数执行后依然没法被销毁 。此时一个完整的闭包实现了, js 的垃圾回收机制因为闭包的存在没法销毁变量 a。咱们利用闭包,在函数外层仍是访问到了 a ,保存了函数内部的细节。这就是闭包的所有。由此得来下面定义:code

4.闭包是阻止垃圾回收机制在内存中销毁变量的方法,使得在建立变量的执行环境外能够访问到该变量

上面这段话来自 单页Web应用 JavaScript 从前端到后端 P49,我的认为这本书也是对闭包解释最为详尽生动的一本书。由于此书中大量使用了模块模式因此对闭包的解释十分详尽。

总结一下:闭包是由函数产生的「函数能够建立新的做用域」,当咱们把它赋值给一个变量后,一个完整的闭包出现了。它阻止了 js 的垃圾回收机制对函数内部变量的回收,致使函数内部变量的引用计数一直不为 0,没法被垃圾收集器回收。因此咱们常听乱用闭包可能致使内存泄漏,就是由于闭包的这个特色。

函数做用域的特性让咱们能够从函数内部取得函数外部的变量,而闭包提供了一种反向的操做可能 -- 咱们在函数的外部也能够取得函数内部的变量

闭包是函数外能够访问函数内变量的实现

其它:
StackOverflow 闭包是什么
闭包的用处:You-Dont-Know-JS

相关文章
相关标签/搜索