• JS的解析与执行过程—全局预处理阶段之全局词法环境对象


    问题:有如下代码

    1 var a = 1;
    2 function pop() {
    3     alert(a);
    4     var a = 5;
    5 }
    6 pop();//执行结果,弹出undefined

    这段代码的执行结果为undefined,为什么呢?

    JS的解析与执行并不是读一行,处理一行,读一行,处理一行这样进行的,而是分为两个阶段:

    1、预处理阶段;

    2、执行阶段;

    然后分别以全局和函数内部的局部代码而言:

    1、全局预处理

    在解析JS代码的时候,首先会创建一个全局LexicalEnviroment{ }(词法环境)对象

    接下来扫描JS代码里面的两个部分:

    a、用声明的方式创建的函数;

    b、用var定义的变量;

    扫面完毕后将这些变量及函数添加到全局的词法环境对象里面去;

     1 LexicalEnviroment: {
     2     a: undefined,
     3     b: undefined,
     4     test: 对函数的一个引用
     5 }
     6 
     7 //用声明的方式创建的函数
     8 function test(params) {
     9     
    10 }
    11 //用函数表达式创建的函数
    12 var test1 = function(params) {
    13     
    14 }
    15 //用var定义的变量
    16 var a = 5;
    17 var b;
    18 //其他变量
    19 c = 6;

    定义一个声明函数和一个函数表达式来证明这一点,代码如下:

    1 f();
    2 g();
    3 
    4 function f() {
    5     console.log("ff");
    6 }
    7 var g = function() {
    8     console.log("gg");
    9 }

    得到如下结果:

    1 ff
    2 e:CodeJavaScriptday03	est2.js:2
    3 g();
    4 ^
    5 
    6 TypeError: g is not a function

    函数f被正常执行,而函数g报错了

    因为在预处理阶段,函数f的引用被放在LexicalEnviroment对象中了,而g没有,所以在调用时函数g()并不存在,所以报错。

    改一下位置,这样就对了

    1 f();
    2 var g = function() {
    3     console.log("gg");
    4 }
    5 g();
    6 
    7 function f() {
    8     console.log("ff");
    9 }

    这点在var定义变量上的体现:

    1 console.log(a);
    2 console.log(b);
    3 
    4 var a = 5;
    5 b = 6;

    这段代码的执行结果如下:

    1 undefined
    2 e:CodeJavaScriptday03	est3.js:2
    3 console.log(b);
    4             ^
    5 
    6 ReferenceError: b is not defined

    可见,如上所说,以var方式定义的a被添加到全局LexicalEnviroment{ }(词法环境)对象中了,其值为undefined,而直接定义的b此时不存在,所以报错。

    这就是全局预处理阶段的过程。

    声明:

    关于全局的词法环境对象LexicalEnviroment,在浏览器中就约等于window对象,该对象是属于JS解析器的东西,在不同的地方叫法不同,比如在Node中称为Execute Context(运行上下文对象)或许更合适一点,在ECMA -262标准中有其解释,但我们无需关心其具体含义,只是有这个概念便可。

  • 相关阅读:
    [转] 你不知道的JavaScript和CSS交互的方法
    threejs学习笔记(9)
    把Mongodb配置成windows服务
    mongodb的一些基本操作
    DuiLib事件分析(一)——鼠标事件响应
    DuiLib学习bug整理——某些png不能显示
    DuiLib学习笔记5——标题栏不能正常隐藏问题
    DuiLib学习笔记4——布局
    DuiLib学习笔记3——颜色探究
    DuiLib学习笔记2——写一个简单的程序
  • 原文地址:https://www.cnblogs.com/jixiaohua/p/10480855.html
Copyright © 2020-2023  润新知