js 预编译

更新日期: 2020-02-27阅读: 1.6k标签: 编译器

js 运行代码的时候分为几个步骤:语法分析 ==》预编译  ==》解释执行

语法解析:通篇扫描代码,查看语法是否出错

解释执行读一行 - 解释一行 - 执行一行

 

预编译执行的操作:

// 假设之前并没有定义a
console.log(a);

打印结果:Uncaught ReferenceError: a is not defined

这个大家应该都知道:在变量未定义时就对变量进行访问就会报错(typeof 列外)

 

再看一个例子:

// 假设之前并没有定义变量a
console.log(a);
var a = 123;
console.log(a);

看上面代码会打印什么?会不会报错?

打印结果:

undefined
123

为什么这个没有报错:因为在预编译的时候对变量进行了提升即变量提升。 定义的变量的声明(var a ;)被提到了代码块的最前面,变量的赋值操作(a = 123)没有变化。

所以被编译后就相当于

// 假设之前没有定义变量a
var a;
console.log(a);
a = 123;
console.log(a);

 

看下面这个例子:

// 假设之前没有定义test
console.log(test);
var test = 123; 
function test () {

}
console.log(test);

打印结果:

function test () {}
123

为什么第二行的输出的不是undefined 了?执行步骤是什么样子的?

因为函数声明在编译的时候也会进行提升,叫做函数提升

执行步骤:

1、变量提升:var test; 提升到最前面。此时test = undefined;

2、函数提升:function test () {}; 提升到最前面并覆盖var test; 的声明。所以第二行打印function test () {}; 此时test = function test () {}

3、进行赋值操作 test = 123; 此时test = 123;

function test (test) {
  console.log(test);  // function test(){var a = 789}
   var test = 123;
   function test () {
       var a = 789;
    };
   console.log(test) ;  // 123     
}

test(456);

Why?

 

变量提升和函数提升是如何实现的?

预编译执行步骤

(a) 函数内

 1、在代码定义之后执行之前生成AO(Activation Object ) 空对象{}

 2、查找函数体内的形参和变量,定义为AO的属性,赋值为undefined;

 3、将实参跟形参统一,即把实参赋值给AO[形参]

 4、查找函数里的函数声明,将函数声明赋值给AO 即 AO[函数名] = 函数

(b) 全局

 1、在代码定义之后执行之前生成GO(Global Object ) 空对象{}

 2、查找变量,定义为GO的属性,赋值为undefined;

 3、查找函数声明,将函数声明赋值给GO 即 GO[函数名] = 函数;

 

以上面的例子分析预编译过程:

function test (test) {
   console.log(test);  // function test(){var a = 789}
    var test = 123;
    function test () {
        var a = 789;
     };
    console.log(test) ;  // 123     
 }
 
test(456);

var a = 111;

/** 全局 **/ // 第一步:创建GO // GO{}; // 第二步:查找变量定义为GO的属性,赋值为undefined;
// GO{
// a: undefined
// };
// 第三步:将函数声明赋值给GO
// GO{
// a: undefined,
// test: function test(test) {...}
// }

/** function test(test){...} 函数内 **/
// 第一步: 创建AO
// AO {}
// 第二步: 查找形参和变量,定义为AO的属性, 赋值为undefined;
// AO {
// test: undefined
// }
// 第三步: 形参和实参统一
// AO {
// test: 456
// }
// 第四步:将函数声明给AO
// AO {
// test: function test() { var a = 789 }
// }

 

之后就是一步一步的执行代码了

function test (test) {
   console.log(test);  // function test(){var a = 789}
    var test = 123;
    function test () {
        var a = 789;
     };
    console.log(test) ;  // 123     
 }
 
test(456);

var a = 111;

// test(456); 进入到function test (test) {...} 内部
// console.log(test); // 打印 function test(){var a = 789}
// var test = 123; 由于 test 变量的声明已经提升,所以这句只执行 test = 123; 即AO[test] = 123
// AO {
//   test: 123
// }
// function test() {var a = 789} 已经提升
// console.log(test) //打印 123
// 退出function test (test) {...} 销毁AO
// var a = 111; 由于 a 变量已经提升,这句只执行赋值 a = 111; 即 GO[a] = 111;
// GO{
//   a: 111,
//   test: function test(test) {...}
// }

// 当页面销毁时销毁GO

 原文:https://www.cnblogs.com/linyabin/p/12371740.html


链接: https://fly63.com/article/detial/7956

200行代码实现超轻量级编译器

本篇和大家一起学习写一款超级简单轻量,去掉注释只有不到200行代码的编译器。,该编译器将类 lisp 语法函数调用 编译为 类C语言函数调用

javascript有编译器吗?

javascript没有编译器,因为它是一种解释型语言。javascript是由javascript引擎解释执行的,不需要编译器。而javascript引擎一般是嵌入在其它的软件中,如各种浏览器中。

用 JavaScript 写一个超小型编译器

这是一个用JavaScript编写的编译器,虽然是一个很小很小的并没有什么卵用的编译器,但可以向我们展示编译器的很多东西。今天我把它翻译了出来,供大家学习和讨论。

css预编译器有哪些?

预编译又称为预处理,是做些代码文本的替换工作预编译又称为预处理,CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言。

通过编译器插件实现代码注入

大型的前端系统一般是模块化的。每当发现问题时,模块负责人总是要重复地在浏览器中找出对应的模块,略读代码后在对应的函数内打上断点,最终开始排查。

前端实现多文件编译器

在前端工程中,有时我们需要在浏览器编译并执行一些代码,这种需求常见于低代码场景中。例如我们在搭建时需自定义一部分代码,这些代码需要在渲染时执行。为了方便起见,我们写的代码一定是 ES6 语法

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!