JS对闭包和作用域链的理解

最近除了尝试一些新的技术以外,更喜欢把时间花在研究JS的基础知识上,让我对JS很多底层实现的理解加深了不少,今天闲来无事就和各位兄台交流一下,说说我自己对JS中作用域,作用域链和闭包的理解吧,如有不对的地方,希望各位兄台多多包涵,欢迎留言纠正。

作用域:

首先来聊聊作用域,其实在我个人理解中作用域更像是JS中的一种规则,在代码编译的时候就已经确定了该变量是属于什么变量并且拥有什么样的作用域了,简而言之就是规定了能被访问的范围。在只有var定义变量的时代,JS是不存在块级作用域的,只分全局作用域和局部作用域。

全局作用域:

      全局变量拥有全局作用域,从定义变量的位置来看,可以简单理解为不在任何函数内部,也可以说是定义在最外层函数的外面,在定义后可以在任何地方访问到该变量。

局部作用域:

      局部变量拥有局部作用域,只在固定的代码片段中可以访问到,一般是在函数内部定义,所以也可以叫函数作用域。在这里需要提一下,在函数内部不使用var定义而是直接赋值操作的话,生成的并不一定会是局部变量,它更像是在对一个属性赋值操作,首先会在当前作用域链中查找该变量,如果有就会对该变量进行赋值操作,如果没有就会在全局对象中创造一个同名的属性并且赋值,也就是说函数内部直接给一个未定义的变量赋值,并且该变量还不在当前作用域内可以找到的话,就会是一个全局变量。当然这样声明出来的全局变量和在全局作用域中使用var声明出来的全局变量还是有一些差别的,例如前者默认是可配置的,后者默认是不可配置的。在这里还有一点比较特殊,只要在函数内定义了一个局部变量,在该函数被解析的时候是会将这个变量提前声明的,也就是说在一个函数内部不管变量在哪一行定义,它的声明都将被放到函数内部的最开始处,当然什么时候赋值还是得看变量在哪一行赋值的才行,在赋值之前都会被undefined替代但并不会报错。

作用域链:

什么是作用域链呢?我的理解就是,如果在一个函数内部声明一个变量和一个函数,内部的函数可以访问到外部函数的变量这种规则或者说是这种机制,就是作用域链,用链式的方法单向的一层一层往外查找。想要具体了解这个规则,我们得先了解一下JS的执行环境。

执行环境:

执行环境也可以叫作执行上下文,当JS解释器初始化执行代码时,它首先默认进入全局执行环境,从此刻开始,函数的每次调用都会创建一个新的执行环境,那怕同一个函数被调用多次,执行环境也会创建多个,并且每个执行环境关联一个变量对象也可以称作活动对象,在此环境中定义的变量和函数都会被保存到这个变量对象中。当一个函数被调用时,该函数关联的变量对象就会被放入一个环境栈中,在该函数执行完之后,对应的变量对象将被弹出,把控制权交给之前的执行环境变量对象。

大概讲述了一下执行环境后在回过来讲述一下作用域链。

当我们第一次调用一个函数的时候,会创建执行环境以及变量对象的一个作用域链,并把作用域链赋值给了一个内部的属性([scope])。作用域链主要是保证在执行中有序的去访问变量或者函数,在作用域链中包含了环境栈中的每一个执行环境关联的变量对象,由此可以决定变量是否在访问范围内,全局对象始终都会是作用域链的最后一个对象,当前执行的活动对象才会是第0位对象。访问一个变量时,是沿着作用域链一级一级的搜索,从第0位开始逐步往后搜索,直到找到标识符为止,所以外部环境是不可以直接访问内部环境的变量和函数的,但是内部环境却是可以访问到外部环境的变量和函数的,这里的内部环境就是处于环境栈中第0位的活动对象。

闭包:

在刚开始接触JS的很长一段时间中,我对闭包的概念一直很模糊,工作中也很少用到,但是其实闭包的作用很强大。当一个执行环境中所有代码执行完毕后,该变量对象应该被弹出环境栈,随即销毁,内部的变量和函数也应该随之消失,但是当调用闭包时,会生成一个全新的执行环境和作用域链,虽然闭包的外部函数已经执行结束了,环境被销毁了,但是其关联的活动对象在闭包的作用域链中被引用,所以并不会被销毁而是会一直存在内存中。 其实说了这么多,可能有点复杂,我简单概括为两点:

      第一点是可以读取到将闭包嵌套在内部的函数的变量,无论在闭包外嵌套了多少层函数,这些函数的变量都可以在闭包内部访问到(用作用域链搜索)。

      第二点是让这些外部变量始终都保存在内存中,提高执行速度,因为这一点所以使用闭包也要特别注意,如果滥用闭包很容易引起内存泄漏。我对于闭包的使用主要集中在这几点,例如需要处理一个过程比较复杂耗时很长的函数,每次重复调用都会花很长时间,那我会使用闭包将这个结果储存起来,提高执行速度;还有例如想要访问外部函数中的变量或者参数,即使是在执行完毕以及被销毁之后,可以使用闭包来返回这些本该被销毁的变量和参数。

结尾:

今天就说这么多,打了这么多字好累啊,都是我自己的理解结合工作上使用的一些经验之谈,如有不妥之处随时欢迎指正,下一次我们再来聊聊JS中原型和原型链是个啥,仅仅是为了定义一些公用的方法吗,似乎没有想象中这么简单哦?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容