资讯专栏INFORMATION COLUMN

javascript闭包不完全探索记录01:闭包?啥馅的?

TANKING / 2851人阅读

摘要:闭包一词来源于以下两者的结合要执行的代码块由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放和为自由变量提供绑定的计算环境作用域。在以及及以上等语言中都能找到对闭包不同程度的支持。

温馨提示:作者的爬坑记录,对你等大神完全没有价值,别在我这浪费生命

闭包,好吃吗 ?

第一次听到这个词,很不幸是在一次面试中,可想而知结果很细碎,从此“闭包”和“跨域”在我匮乏的前端知识中成为了两座无法翻阅的大山,即便一度转设计,还是活在他们的阴影之下。

不过怎么说呢。缘,妙不可言,感谢某司让我猝不及防的重新走上了前端之路,既然又走回来了,一个前端工程师的(伪)的自尊告诉我这回必须要刚正面了

一听这个词,我就一脸懵逼,这是个名词,还是个动词?这是个包?还是个什么操作?我觉得对这个词本身的认识,在了解一个事物上非常重要,而且经验告诉我对于这种看上去就知道是被专(hu)业(bi)翻译过来的外来词汇,千万不要尝试通过中文字面意义去理解他,一定要去看看它在英文中的意思

closure    英[ˈkləʊʒə(r)] 美[ˈkloʊʒə(r)]
n.结束; (永久的) 停业,关闭; [电] 闭合; [数] 闭包;
vt. 使结束,使终止; 使停止辩论;

这下明白了,这货是个名词,这下对他能有一个客观的认识了,“闭包”这个词,他就是一个东西,一个结束了,关闭了,闭合了的东西

下面在看看*度百科上面定义

闭包包含自由(未绑定到特定对象)变量;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。在PHP、Scala、Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby、 Python、Go、Lua、objective c、swift 以及Java(Java8及以上)等语言中都能找到对闭包不同程度的支持。

怎么说呢,我坚信这不是人话,经过翻译,说了两件事:

闭包中有一堆不被释放的变量(这就明白什么为什么叫closure了)

很多语言都有(本文只看javascript)

闭包,什么样?

经过上面对闭包概念的初步理解,知道了这是一个包含一堆没有被释放的变量的东西,那这货在javascript中到底是以什么样的形式存在的呢?

知乎上的相关回答五花八门,从各个角度都有很是精彩但是容易懵逼
如何才能通俗易懂的解释javascript里面的‘闭包’? - 知乎
所以不妨先去看看大神相对“正统”博文
学习Javascript闭包(Closure)- 阮一峰
JavaScript之作用域与闭包详解 - 默语

总之,大家都提到了要从javascript变量的作用域的一个特点开始说起

变量的作用域无非就是两种:全局变量和局部变量。
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。
每次定义一个函数,都会产生一个作用域链(scope chain)。当JavaScript寻找变量varible时(这个过程称为变量解析),总会优先在当前作用域链的第一个对象中查找属性varible ,如果找到,则直接使用这个属性;否则,继续查找下一个对象的是否存在这个属性;这个过程会持续直至找到这个属性或者最终未找到引发错误为止。

可以理解为,javascript有一个特点,就是在函数中,有“作用域链”这么个东西,大概意思是,你作为函数中的一个变量,在找自己的值的时候,是从里往外找的,你要先看自己所在函数中有没有给你赋值,没有就往外走,看看你外面一层有没有,直到找到或者找不到报错为止。
因为有这个原理的存在,也就能解释为什么函数内部可以读取外部的变量了

下面我们来做个实验:

var a = "a";
var b = "b";
function test(){
    var c = "c";
    var b = "d"
    function testInner(){
        console.log(a);//a
        console.log(b);//d
        console.log(c);//c
    }
    testInner();
}
test();
console.log(b);//b,
console.log(d);//ReferenceError: d is not defined

结果可知:

函数内部可以读取外部函数变量,以及全局变量,并且是由内向外读取的

函数外部无法读取内部的变量(废话)

那如果我们要是想在外面get到函数内部变量的值呢?这个变量谁知道呢,答案是显而易见的

他的内部函数是可以读取他外部函数变量的,而这个内部函数就是一个闭包
//下文有更新

讲个故事来说,老王对自己的儿子小王(内部函数)是无话不说的,但是对自己的老婆(老王的上一层)却习惯性装傻,于是王太太就只能通过小王知道老王的私房钱在哪了,而这个带着私房钱信息的小王就是闭包。

这就又有一个问题了,王太太是怎么找到小王的呢/外部如何才能得到内部函数的呢,这简单,老王喝多了自己让王太太带小王去玩的/函数将内部函数作为返回值

看下面这个例子:

function getMoneyInfo(){
    var moneyInfo = "马桶水箱里";
    function askXiaoWang(){
        return moneyInfo
    }
    return askXiaoWang()
}
console.log(getMoneyInfo())//马桶水箱里
console.log(moneyInfo)//ReferenceError: moneyInfo is not defined

看到这里,感觉对闭包是个啥,以及是怎么来的有了个大概的认识,但是他具体是干啥的,有什么非用不可的好处,以及除了面试到底有什么应用场景,将在今后继续学习!

看到这里的都是真爱

20171126:更正与补充
经过对各大神的博文再次阅读,发现上文有些事情还是没说清楚:

既然closure有闭合和结束的意思,那到底是什么被关闭和结束了呢,也就是说是什么保持了一个不变的状态呢
是这个函数以及其所引用的变量

闭包的产生,之所以是closure,是因为由于在更外层调用了内部的函数,所以与这个函数所相关的一切都不能在外层工作完成前被释放,这也就是所谓的闭合和结束了,也就是会一直保持一种不变的状态。

说句人话,按照老王之前的习惯,私房钱(似有变量)用完了,下次再有私房钱(函数再次被调用)就换个地方(内存中),老婆根本不可能找得到,但是现在有了小王(内部函数)在,他一直被他妈安排盯着厕所水箱,老王就是想花钱都没法花了,对他来说,这点钱算是结束(closure)了,而在这看着钱的小王,就是一个所谓的闭包了

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

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

相关文章

  • javascript闭包完全探索记录02:闭包?干嘛使!

    摘要:温馨提示作者的爬坑记录,对你等大神完全没有价值,别在我这浪费生命温馨提示续本文将会成为一篇笔记类型的文章,记录闭包具体的应用方式温馨提示再续本文存在错误,会慢慢改进的,请不要把我说的当真在上一篇博文闭包不完全探索记录闭包啥馅的中,对中 温馨提示:作者的爬坑记录,对你等大神完全没有价值,别在我这浪费生命温馨提示-续:本文(maybe)将会成为一篇笔记类型的文章,记录闭包具体的应用方式温馨...

    Render 评论0 收藏0
  • javascript对象完全探索记录01:this! which?

    温馨提示:作者的爬坑记录,对你等大神完全没有价值,别在我这浪费生命 这一切,源于阮大神博文学习Javascript闭包(Closure)- 阮一峰中的一道思考题 //问题1: var name = The Window; var object = {   name : My Object,   getNameFunc : function(){     return function(){    ...

    rubyshen 评论0 收藏0
  • JavaScript 是如何工作的:模块的构建以及对应的打包工具

    摘要:挂机科了次使用这个结构,匿名函数就有了自己的执行环境或闭包,然后我们立即执行。注意,匿名函数的圆括号是必需的,因为以关键字开头的语句通常被认为是函数声明请记住,中不能使用未命名的函数声明。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第 20 篇。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 如果你错过了前面的章节,可以在这里找到它们: ...

    hedzr 评论0 收藏0
  • 翻译连载 | JavaScript轻量级函数式编程-第7章: 闭包vs对象 |《你知道的JS》姊妹

    摘要:相像闭包和对象之间的关系可能不是那么明显。一个没有对象的编程语言可以用闭包来模拟对象。事实上,表达一个对象为闭包形式,或闭包为对象形式是相当简单的。简而言之,闭包和对象是状态的同构表示及其相关功能。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,...

    leanxi 评论0 收藏0
  • 学习JavaScript之内存泄漏

    摘要:接上回我写了一篇关于闭包的博客学习之闭包,最后谈到闭包导致的问题时留了一个尾在以下的浏览器中会有内存泄漏的问题。今天的博客就继续探索一下内存泄漏的问题。博客地址的前端之路原文链接学习之内存泄漏 接上回我写了一篇关于闭包的博客《学习JavaScript之闭包》, 最后谈到闭包导致的问题时留了一个尾: 在IE9以下的浏览器中会有内存泄漏的问题。 今天的博客就继续探索一下内存泄漏的问题。 浅...

    nodejh 评论0 收藏0

发表评论

0条评论

TANKING

|高级讲师

TA的文章

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