Js作用域 和作用域链

194 阅读4分钟

干货!干货!干货!

接着上文我们进行作用域和作用域链的分析

如果这一章节大家看不懂,请翻看我上一篇文章预编译

正题:

Javascript作用域 和 作用域链

开始之前我们分析一下:

js中每个函数都是一个对象 ,每个对象属性,对,只要你是个对象,你就属性,对象的有些属性我们可以访问,有些不可以访问,这些我们不能访问的属性被称为隐式属性,隐式属性仅供js引擎读取,而今天我们的主角[[scopes]]就是其中一个不能访问的隐式属性。

作用域:

[[scopes]]指的就是作用域,里面存储了执行上下文的集合

作用域链:

[[scopes]]中存储的是执行期上下文的集合

这个集合呈链式链接,这个链式链接叫做作用域链 我们可以理解为一个数组

[[scopes]]隐式属性是在函数定义的时候产生 在函数执行的前一刻调用

[[scopes]]属性记录当前函数的执行环境

提示:

大家简单阅读上面的话就行了,读完估计就理解不了了,但还是要读一下,咱们接着往下面看

请仔细阅读:

 function a() {
     function b() {
         function c() {
             
         }
         c();
     }
     b();
 }
 a();
 ​
 大家请仔细观看分析a,b,c之间微妙的关联:
 ​
 a 定义 a.[[scopes]] ===>  0: GO {}
 a 执行 a.[[scopes]] ===>  0: a-AO {}
                          1: GO {}
                         
 b 定义 b.[[scopes]] ===> 0: a-AO {}
                         2: GO {}
                         
 b 执行 b.[[scopes]] ===>  0: b-AO {}
                          1: a-AO {}
                          2: GO {}
                         
 c 定义 c.[[scopes]] ===>  0:b-AO {}
                          1:a-AO {}
                          2:GO {}
                         
 c 执行 c.[[scopes]] ===>  0:c-AO {}
                          1: b-AO {}
                          2: a-AO {}
                          3: GO {}

大家记住,a定义的时候生成的是GO,在第0位,当a执行,a会生成AO,这时候AO就变成了第0位,GO变成了第一位,这时候到b定义了,大家仔细看代码分析,b定义的时候有什么区别,b这个时候是拿的a的劳动成果,拿的是a的AO和GO,等于说b是站在a的肩膀上出生的,拿的是a的劳动成果,大家一定记好。

大家记住只有当函数a执行,才能导致b定义,在次强调,b定义的时候拿的是a的劳动成果,当b执行的时候才生成自己的AO。

小笑话:

a:你小子挺鸡贼啊,我干了半天活,你小子一滴汗没出就把我劳动成果拿走了?

b:这个......,这个作者非要这样说。

注意!:

c这时候出来了,c拿谁的劳动成果呢?大家请仔细观看图片

小笑话:

c:我该拿谁的劳动成果呀?

a:睁大你的眼睛看看你是在谁的肩膀上站着的。

c:奥奥,我明白了,我在b肩膀上踩了老半天了

大家注意,c定义的时候拿的是b的劳动成果,等到c执行的前一刻,c才生成自己的AO。

这时候,c身上有b的劳动成果,而b身上有a的劳动成果,这时候在大家仔细品味,像什么东西?是不是像一条链子?互相把对拴住。

没错,这就是所谓的作用域链。

这时候我们来解释一下什么是执行上下文的集合

执行上下文:

当函数执行的时候函数内部的 变量 形参 函数内部函数 一个执行期上下文定义了一个 函数执行时的环境 函数内执行时对应的执行上下文都是独一无二的,多次调用函数一个函数会创建一个多个执行上下文,当函数执行完毕,它所产生的执行上下文被销毁

注意:

在函数执行的前一刻 生成AO对象

会创建一个AO当执行完毕的时候销毁AO

知识点:

在哪个函数里面查找变量,就在哪个函数的作用域链顶端依次向下查找

作用域链的作用:

访问变量或者函数时候,会在作用域链上依次查找,最直接的表现就是。内部函数可以使用外部函数声明的变量

内部函数可以使用外部函数的变量

外部函数不能使用内部函数的变量

但这样很容易形成闭包,这就是我们下一个文章要写的文章,闭包

本期内容到此结束,谢谢大家观看!

\