干货!干货!干货!
接着上文我们进行作用域和作用域链的分析
如果这一章节大家看不懂,请翻看我上一篇文章预编译
正题:
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
知识点:
在哪个函数里面查找变量,就在哪个函数的作用域链顶端依次向下查找
作用域链的作用:
访问变量或者函数时候,会在作用域链上依次查找,最直接的表现就是。内部函数可以使用外部函数声明的变量
内部函数可以使用外部函数的变量
外部函数不能使用内部函数的变量
但这样很容易形成闭包,这就是我们下一个文章要写的文章,闭包
本期内容到此结束,谢谢大家观看!
\