22
33# 前言
44
5- 在《JavaScript深入之执行上下文栈》中讲到,当JavaScript代码执行一段可执行代码 (executable code)时,会创建对应的执行上下文(execution context)。
5+ 在[ 《JavaScript深入之执行上下文栈》] ( https://github.com/mqyqingfeng/Blog/issues/4 ) 中讲到,当 JavaScript 代码执行一段可执行代码 (executable code)时,会创建对应的执行上下文(execution context)。
66
77对于每个执行上下文,都有三个重要属性:
88
99* 变量对象(Variable object,VO)
1010* 作用域链(Scope chain)
1111* this
1212
13- 然后分别在《JavaScript深入之变量对象》《JavaScript深入之作用域链》《JavaScript深入之从ECMAScript规范解读this》中讲解了这三个属性。
13+ 然后分别在[ 《JavaScript深入之变量对象》] ( https://github.com/mqyqingfeng/Blog/issues/5 ) 、 [ 《JavaScript深入之作用域链》] ( https://github.com/mqyqingfeng/Blog/issues/6 ) 、 [ 《JavaScript深入之从ECMAScript规范解读this》] ( https://github.com/mqyqingfeng/Blog/issues/7 ) 中讲解了这三个属性。
1414
15- 阅读本文前,如果对以上概念不是很清楚,希望先行阅读这些文章 。
15+ 阅读本文前,如果对以上的概念不是很清楚,希望先阅读这些文章 。
1616
17- 这一章,我们会结合着所有内容,讲讲执行上下文的具体处理过程。
17+ 因为,这一篇,我们会结合着所有内容,讲讲执行上下文的具体处理过程。
18+
19+ ## 思考题
20+
21+ 在[ 《JavaScript深入之词法作用域和动态作用域》] ( https://github.com/mqyqingfeng/Blog/issues/3 ) 中,提出这样一道思考题:
22+
23+ ``` js
24+ var scope = " global scope" ;
25+ function checkscope (){
26+ var scope = " local scope" ;
27+ function f (){
28+ return scope;
29+ }
30+ return f ();
31+ }
32+ checkscope ();
33+ ```
34+
35+ ``` js
36+ var scope = " global scope" ;
37+ function checkscope (){
38+ var scope = " local scope" ;
39+ function f (){
40+ return scope;
41+ }
42+ return f;
43+ }
44+ checkscope ()();
45+ ```
46+
47+ 两段代码都会打印'local scope'。虽然两段代码执行的结果一样,但是两段代码究竟有哪些不同呢?
48+
49+ 紧接着就在下一篇[ 《JavaScript深入之执行上下文栈》] ( https://github.com/mqyqingfeng/Blog/issues/4 ) 中,讲到了两者的区别在于执行上下文栈的变化不一样,然而,如果是这样笼统的回答,依然显得不够详细,本篇就会详细的解析执行上下文栈和执行上下文的具体变化过程。
1850
1951## 具体执行分析
2052
21- 依然是以《JavaScript深入之执行上下文栈》中权威指南的例子进行讲解,毕竟是说了要具体讲解两个例子之间有什么不同 :
53+ 我们分析第一段代码 :
2254
2355``` js
2456var scope = " global scope" ;
@@ -52,15 +84,15 @@ checkscope();
5284 }
5385```
5486
55- 2.初始化的同时,checkscope函数被创建,保存作用域链到 [[ scope]]
87+ 2.初始化的同时,checkscope 函数被创建,保存作用域链到函数的内部属性 [[ scope]]
5688
5789``` js
5890 checkscope.[[scope]] = [
5991 globalContext .VO
6092 ];
6193```
6294
63- 3.执行checkscope函数,创建checkscope函数执行上下文,checkscope函数执行上下文被压入执行上下文栈
95+ 3.执行 checkscope 函数,创建 checkscope 函数执行上下文,checkscope 函数执行上下文被压入执行上下文栈
6496
6597``` js
6698 ECStack = [
@@ -69,14 +101,14 @@ checkscope();
69101 ];
70102```
71103
72- 4.checkscope函数执行上下文初始化 :
104+ 4.checkscope 函数执行上下文初始化 :
73105
74- 1 . 复制函数[[ scope]] 属性创建作用域链,
75- 2 . 用arguments创建活动对象 ,
106+ 1 . 复制函数 [[ scope]] 属性创建作用域链,
107+ 2 . 用 arguments 创建活动对象 ,
761083 . 初始化活动对象,即加入形参、函数声明、变量声明,
77- 4 . 将活动对象压入checkscope作用域链顶端 。
109+ 4 . 将活动对象压入 checkscope 作用域链顶端 。
78110
79- 同时f函数被创建 ,保存作用域链到[[ scope]]
111+ 同时 f 函数被创建 ,保存作用域链到 f 函数的内部属性 [[ scope]]
80112
81113``` js
82114 checkscopeContext = {
@@ -92,7 +124,7 @@ checkscope();
92124 }
93125```
94126
95- 5.执行f函数,创建f函数执行上下文,f函数执行上下文被压入执行上下文栈
127+ 5.执行 f 函数,创建 f 函数执行上下文,f 函数执行上下文被压入执行上下文栈
96128
97129``` js
98130 ECStack = [
@@ -102,12 +134,12 @@ checkscope();
102134 ];
103135```
104136
105- 6.f函数执行上下文初始化, 以下跟第4步相同 :
137+ 6.f 函数执行上下文初始化, 以下跟第 4 步相同 :
106138
107- 1 . 复制函数[[ scope]] 属性创建作用域链
108- 2 . 用arguments创建活动对象
139+ 1 . 复制函数 [[ scope]] 属性创建作用域链
140+ 2 . 用 arguments 创建活动对象
1091413 . 初始化活动对象,即加入形参、函数声明、变量声明
110- 4 . 将活动对象压入checkscope作用域链顶端
142+ 4 . 将活动对象压入 f 作用域链顶端
111143
112144``` js
113145 fContext = {
@@ -121,9 +153,9 @@ checkscope();
121153 }
122154```
123155
124- 7.f函数执行,沿着作用域链查找scope值,返回scope值
156+ 7.f 函数执行,沿着作用域链查找 scope 值,返回 scope 值
125157
126- 8.f函数执行完毕,f函数上下文从执行上下文栈中弹出
158+ 8.f 函数执行完毕,f 函数上下文从执行上下文栈中弹出
127159
128160``` js
129161 ECStack = [
@@ -132,15 +164,15 @@ checkscope();
132164 ];
133165```
134166
135- 9.checkscope函数执行完毕,checkscope执行上下文从执行上下文栈中弹出
167+ 9.checkscope 函数执行完毕,checkscope 执行上下文从执行上下文栈中弹出
136168
137169``` js
138170 ECStack = [
139171 globalContext
140172 ];
141173```
142174
143- 最后关于另一个例子:
175+ 第二段代码就留给大家去尝试模拟它的执行过程。
144176
145177``` js
146178var scope = " global scope" ;
@@ -154,16 +186,16 @@ function checkscope(){
154186checkscope ()();
155187```
156188
157- 大家可以去尝试着模拟它的执行过程 。
189+ 不过,在下一篇《JavaScript深入之闭包》中也会提及这段代码的执行过程 。
158190
159- 不过,在下一篇讲闭包的文章中也会提及这个例子的执行过程。
191+ ## 下一篇文章
160192
161- 最后,因为都是讲权威指南书上的这个例子,而且写之前看了这篇文章
162- [ https://github.com/kuitos/kuitos.github.io/issues/18 ] ( https://github.com/kuitos/kuitos.github.io/issues/18 )
163- 写完后总感觉像是抄袭别人的,只能说写的太好,给了我很多影响。感激不尽!
193+ [ 《JavaScript深入之闭包》] ( https://github.com/mqyqingfeng/Blog/issues/9 )
164194
165195## 相关链接
166196
197+ [ 《JavaScript深入之词法作用域和动态作用域》] ( https://github.com/mqyqingfeng/Blog/issues/3 )
198+
167199[ 《JavaScript深入之执行上下文栈》] ( https://github.com/mqyqingfeng/Blog/issues/4 )
168200
169201[ 《JavaScript深入之变量对象》] ( https://github.com/mqyqingfeng/Blog/issues/5 )
@@ -172,6 +204,12 @@ checkscope()();
172204
173205[ 《JavaScript深入之从ECMAScript规范解读this》] ( https://github.com/mqyqingfeng/Blog/issues/7 )
174206
207+ ## 重要参考
208+
209+ [ 《一道js面试题引发的思考》] ( https://github.com/kuitos/kuitos.github.io/issues/18 )
210+
211+ 本文写的太好,给了我很多启发。感激不尽!
212+
175213## 深入系列
176214
177215JavaScript深入系列目录地址:[ https://github.com/mqyqingfeng/Blog ] ( https://github.com/mqyqingfeng/Blog ) 。
0 commit comments