资讯专栏INFORMATION COLUMN

深入理解 Javascript 之 JS的解析与执行过程

amuqiao / 1556人阅读

摘要:的解析与执行过程第一个弹出函数体第二个弹出函数体第三个弹出第四个弹出第五个弹出最后一行报错执行分析第行,没有关键字,不解析第行,遇到关键字,解析到全局的头部第行,没有关键字,不解析第行,遇到关键字,解析到全局的头部第行,没有关键

js的解析与执行过程

</>复制代码

  1. alert(a);
  2. function a(){ alter(2); }
  3. alert(a);
  4. var a = 1
  5. alert(a);
  6. var a = 3;
  7. alert(a);
  8. function a(){ alter(4); }
  9. alert(a);
  10. a();

</>复制代码

  1. - 第一个 alert(a) 弹出 function a(){ alter(4); } 函数体
  2. - 第二个 alter(a) 弹出 function a(){ alter(4); } 函数体
  3. - 第三个 alter(a) 弹出 1
  4. - 第四个 alter(a) 弹出 3
  5. - 第五个 alter(a) 弹出 3
  6. - 最后一行报错 a is not a function

执行分析

</>复制代码

  1. // 第1行,没有关键字 , 不解析
  2. // 第2行,遇到 function 关键字,解析到全局的头部
  3. a = function a(){ alter(2); }
  4. // 第3行,没有关键字 , 不解析
  5. // 第4行,遇到关键字 var , 解析到全局的头部
  6. a = undefined
  7. // 第5行,没有关键字 , 不解析
  8. // 第6行,遇到关键字 var , 解析到全局的头部
  9. a = undefined
  10. // 第8行,遇到 function 关键字,解析到全局的头部
  11. a = function a(){ alter(4); }
  12. // 第9行,没有关键字 , 不解析
  13. // 第10行,a() 函数调用

</>复制代码

  1. 此时这里有4个同名变量 a ,依循规则是:function 优先与 var, 同名的后面覆盖前面的
    因此,a = function a(){ alter(2); } 替换掉下面的2个 a = undefined ,a = function a(){ alter(4); } 又替换掉 a = function a(){ alter(2); } ,最终只剩下 a = function a(){ alter(4); }

接下来我们进入正题哦

一、 全局预处理和执行 1.1、全局预处理阶段

实例0

</>复制代码

  1. var a = 5;
  2. var b ;
  3. function xxx(){
  4. // 用声明的方式创建的函数
  5. }
  6. var fun = function () {
  7. // 用函数表达式创建的函数
  8. }
  9. c = 5; // 不会报错,但是也不会加入词法环境

</>复制代码

  1. 假设全局我们创建了上诉的内容

首先js会创建一个词法环境对象LexicalEnviroment,全局下等同于我们的window

</>复制代码

  1. // 创建词法环境如下
  2. LexicalEnviroment{
  3. a: undefined
  4. b: undefined
  5. xxx: 该函数的引用
  6. fun: undefined
  7. }
  8. // 这里有着变量提升的知识

实例1

</>复制代码

  1. f(); // ff
  2. g(); // 报错: g is not a function
  3. function f(){
  4. console.log("ff");
  5. }
  6. var g = function() {
  7. //
  8. }
  9. // 【解析】
  10. // 因为词法环境中f存在引用,g确实是undefined,因此当在为g赋值之前调用g会报错。

实例2

</>复制代码

  1. console.log(a); // undefined
  2. console.log(b); // 报错: b is not defined
  3. var a = 1;
  4. b = 4;

实例3 变量重名

</>复制代码

  1. // 处理函数声明冲突 => 覆盖
  2. alert(f);
  3. var f = 0;
  4. function f() {
  5. cosole.log("f");
  6. }
  7. // 执行结果: 弹出一个f函数的字符串
  8. // 处理变量声明冲突 => 忽略
  9. alert(f);
  10. function f() {
  11. cosole.log("f");
  12. }
  13. var f = 0;
  14. // 执行结果: 弹出一个f函数的字符串
  15. // 【解析】
  16. // 可见不是根据最后出现的覆盖前面的
1.2、全局执行阶段

实例 4

</>复制代码

  1. alert(a);
  2. alert(b);
  3. alert(f);
  4. alert(g);
  5. var a = 5;
  6. b = 6;
  7. alert(b);
  8. function f() {
  9. console.log("f");
  10. }
  11. var g = function () {
  12. console.log("g);
  13. }
  14. alert(g);

执行过程如下

</>复制代码

  1. 1. 构建词法环境
  2. 2. 词法环境如下
  3. {
  4. f: function () {console.log("f")}
  5. a: undefined
  6. g: undefined
  7. }
  8. 3. 开始执行
  9. 4. alert(a); // undefined
  10. 5. alert(b); // 报错: b is not defined
  11. 6. alert(f); // function () {console.log("f")}
  12. 7. alert(g); // undefined
  13. 8. a = 5; b = 6 [window下的变量赋值]
  14. 9. alert(b); // 6
  15. 10. g = function () {console.log("g);} [window下的变量赋值]
  16. 11. alert(g); // function () {console.log("g);}
  17. // 最后的词法环境如下(window
  18. {
  19. f: function () {console.log("f")}
  20. a: 5
  21. g: function () {console.log("g);}
  22. b: 6
  23. }
二、 函数预处理和执行 2.1、函数预处理阶段 + 执行阶段

实例 5

</>复制代码

  1. function f(a, b) {
  2. alert(a);
  3. alert(b);
  4. var b = 10;
  5. function a() {
  6. //
  7. }
  8. }
  9. f(1,2);

执行分析

</>复制代码

  1. 1. 1. 构建词法环境
  2. 2. 词法环境如下
  3. {
  4. a: 最初是1, 因为冲突,最后变成了 函数的引用 function a() {// }
  5. b: 2
  6. }
  7. 3. 开始执行
  8. 4. alert(a); // function a() {// }
  9. 5. alert(b); // 2

实例 6

函数内部如果没有用var声明的变量,会成为最外部的词法环境的变量(也就是全局了)

</>复制代码

  1. function a() {
  2. function b() {
  3. c = 100;
  4. }
  5. b();
  6. }
  7. a();
  8. // window.c === 100

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

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

相关文章

  • JS编译 LHS RHS(你不知道JavaScript 小记一)

    摘要:关于两个专业术语的讨论起自对你不知道的一书的阅读学习。遇到,编译器会询问作用域是否已经有一个该名称的变量存在于同一个作用域的集合中。摘录来自你不知道的。 JS 编译之 LHS RHS 一、前言 最近和朋友聊技术的时候,聊到 LHS RHS,我竟然没听说过 没听说过。。。 于是成功引起了我的好奇心。 关于两个专业术语的讨论起自对《你不知道的JavaScript》一书的阅读学习。 二、编译...

    Cristic 评论0 收藏0
  • 【进阶1-2期】JavaScript深入执行上下文栈和变量对象

    摘要:本计划一共期,每期重点攻克一个面试重难点,如果你还不了解本进阶计划,点击查看前端进阶的破冰之旅本期推荐文章深入之执行上下文栈和深入之变量对象,由于微信不能访问外链,点击阅读原文就可以啦。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本周正式开始前端进阶的第一期,本周的主题是调用堆栈,今天是第二天。 本计划一共28期,每期...

    Richard_Gao 评论0 收藏0
  • 《Webkit技术内幕》页面渲染过程

    摘要:文章同步到技术内幕之页面渲染过程最近拜读了传说中的技术内幕一书,有很大收获,尤其是对页面渲染有了较深的认识。解析语法分析,基于词法解释器生成的新标记,构建成抽象语法树,解析器尝试将其与某条语法规则进行匹配。 文章同步到github《Webkit技术内幕》之页面渲染过程 最近拜读了传说中的《Webkit技术内幕》一书,有很大收获,尤其是对页面渲染有了较深的认识。由于功力有限,而且书中设...

    vvpvvp 评论0 收藏0
  • 《Webkit技术内幕》页面渲染过程

    摘要:文章同步到技术内幕之页面渲染过程最近拜读了传说中的技术内幕一书,有很大收获,尤其是对页面渲染有了较深的认识。解析语法分析,基于词法解释器生成的新标记,构建成抽象语法树,解析器尝试将其与某条语法规则进行匹配。 文章同步到github《Webkit技术内幕》之页面渲染过程 最近拜读了传说中的《Webkit技术内幕》一书,有很大收获,尤其是对页面渲染有了较深的认识。由于功力有限,而且书中设...

    adam1q84 评论0 收藏0
  • 《Webkit技术内幕》页面渲染过程

    摘要:文章同步到技术内幕之页面渲染过程最近拜读了传说中的技术内幕一书,有很大收获,尤其是对页面渲染有了较深的认识。解析语法分析,基于词法解释器生成的新标记,构建成抽象语法树,解析器尝试将其与某条语法规则进行匹配。 文章同步到github《Webkit技术内幕》之页面渲染过程 最近拜读了传说中的《Webkit技术内幕》一书,有很大收获,尤其是对页面渲染有了较深的认识。由于功力有限,而且书中设...

    forsigner 评论0 收藏0

发表评论

0条评论

amuqiao

|高级讲师

TA的文章

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