资讯专栏INFORMATION COLUMN

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

keelii / 465人阅读

摘要:完美的闭包,对,闭包就这么简单。这仅仅是闭包的一部分,闭包利用函数作用域达到了访问外层变量的目的。此时一个完整的闭包实现了,的垃圾回收机制由于闭包的存在无法销毁变量。

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

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

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

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

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

3.2闭包就是函数能够记住并访问它的词法作用域,即使当这个函数在它的词法作用域之外执行时

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

闭包的一般定义

闭包是一种抽象概念,每个人对其理解不同,所以有了上面的几种解释。但大家讨论的确是同一个问题。

//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 ,保存了函数内部的细节。这就是闭包的全部。由此得来下面定义:

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

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

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

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

闭包是函数外可以访问函数内变量的实现

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81109.html

相关文章

  • JS 中的闭包是什么?

    摘要:大名鼎鼎的闭包面试必问。闭包的作用是什么。看到闭包在哪了吗闭包到底是什么五年前,我也被这个问题困扰,于是去搜了并总结下来。关于闭包的谣言闭包会造成内存泄露错。闭包里面的变量明明就是我们需要的变量,凭什么说是内存泄露这个谣言是如何来的因为。 本文为饥人谷讲师方方原创文章,首发于 前端学习指南。 大名鼎鼎的闭包!面试必问。请用自己的话简述 什么是「闭包」。 「闭包」的作用是什么。 首先...

    Enlightenment 评论0 收藏0
  • @noescape @escaping @autoclosure

    摘要:默认,弃用,函数结束后,这个闭包的生命周期也将结束。自动闭包默认非逃逸闭包也可以被自动的生成,这种闭包被称为自动闭包,自动闭包自动将表达式封装成闭包。 @noescape 非逃逸闭包 当闭包作为参数传递进函数时,如果这个闭包只在函数中被使用,则开发者可以将这个闭包声明成非逃逸的,即告诉系统当此函数结束后,这个闭包的生命周期也将结束,这样做的好处是可以提高代码性能,将闭包声明成非逃逸的类...

    LucasTwilight 评论0 收藏0
  • 多层级理解闭包

    摘要:第二梯队理解有了第一梯队的认识,我们慢慢修正大脑中对闭包的认识。理解这句话就可以很好的与闭包这两个字关联起来理解闭包这个概念了。总结第二梯队理解闭包是一个有特定功能的函数。第四梯队理解闭包通过访问外部变量,一个闭包可以维持这些变量。 闭包 闭包的概念困惑了我很久,记得当时我面试的时候最后一面有一个问题就是问题关于闭包的问题,然而到现在已经完全不记得当时的题目是啥了,但仍然能够回忆起当时...

    nemo 评论0 收藏0
  • 面试官问我:什么是JavaScript闭包,我该如何回答

    摘要:到底什么是闭包这个问题在面试是时候经常都会被问,很多小白一听就懵逼了,不知道如何回答好。上面这么说闭包是一种特殊的对象。闭包的注意事项通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。从而使用闭包模块化代码,减少全局变量的污染。 闭包,有人说它是一种设计理念,有人说所有的函数都是闭包。到底什么是闭包?这个问题在面试是时候经常都会被问,很多小白一听就懵逼了,不知道如何回答好。这个...

    BenCHou 评论0 收藏0
  • Swift闭包1-基本概念

    摘要:关键字前面的是闭包的申明部分,类似函数的申明,包括参数的申明和返回值的申明后面的部分是闭包的实现。所以,参数类型和返回值类型都可以根据上下文推断出来,那么在闭包里面就可以直接省略。同理,返回值也可以直接省略。 原文链接:http://1199game.com/2016/09/S... 引言   这篇文章开始主要讲解Swift中闭包(Closures)的一些知识点。本文是这个系列的第一篇...

    Nekron 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<