预编译相关内容

js预编译

众所周知javascript是解释性语言,主要特点为解释一行执行一行。

而在js运行时会进行三件事:1语法分析 2.预编译 3.解释执行

语法分析会在代码执行前对代码进行通篇检查,以排除一些低级错误

预编译发生在代码执行的前一刻

解释执行顾名思义就是执行代码

我先给大家举几个预编译的小例子:

var a = 123;

console.log(a);

此时他返回的值会是123;

但如果我们调换位置:

console.log(a);

var a = 123;

我们得到的结果便会是undefined。(由于js解释性语言的原因,先执行console.log,而由于预编译的原因浏览器并不会报错)

如果我们在次尝试不定义变量直接获取:

console.log(a); 此时我们会发现浏览器会进行报错。//Uncaught ReferenceError: a is not defined

这条语句提示我们a没有定义

到这里有些人会有疑问为什么在console.log前,后和不定义a会有如此大的差别,这就是预编译起到的作用

在具体讲解预编译之前要先帮大家了解几点小知识,如下:

预编译的前奏

  1. imply global 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局对象(window)所有。

    简单解释起来就是,如果在js中我们在赋值时经常先定义一个变量,如:var a = 123;

    此时123这个数字便被赋予了a这个变量,此时我们在控制台console.log(a)就会得到a的值123;

    这时就会我们就会有个疑问,如果我们没有定义变量直接进行赋值还会打印出值么。

    答案是肯定的,此时如果我们未定义变量直接赋值,如:

    b = 456;

    此时a会被认为是全局的一个对象,即window下的一个值,此时我们在控制台下console.log(b)同样可以得到b的值456。

    此时我们可以认为 b = 123 ————> window.b =456

  2. 一切声明的全局变量,全是window。

    简单说明就是我们 var c = 789 ===> window.c = 789(即:c =789)

预编译(粗浅版本)

下面我们来看一下对预编译最基本的肤浅理解(该理解非常粗浅无法解决复杂问题):

函数声明整体提升

变量,声明提升

个人理解:在函数执行前函数声明(function(){})会整体提升至逻辑的最前方,

变量则会把自身的声明提升到程序的最最前方。

//注释 var a =123;是变量声明+赋值

var a:变量声明

a = 123 变量赋值

在预编译时我们不看赋值,只把变量的声明提升,因此若在赋值前打印会提示undefined;

此时我们就可以理解之前的问题了:

先打印再定义:

console.log(a);

var a = 123;

在执行前var a提升至代码的最最前端 ,提升后我们再打印 a,由于此时a未被赋值因此打印提示undefined。

console.log(a);

不定义:

console.log(a);

此时由于没有a的定义,所以会报错提示a is not defined;即:a未定义。

看似很好理解但是如果代码稍微复杂便无法解决,例如:

            console.log(a);   fun

            function a(a) {

                        var  a  =  456;

                        var  a   =function  ()  {

                }

                       a();

            }

                    var  a  =   123;

下面我们来看一下真正的预编译:

预编译(精装版本):

预编译的四部曲:

1.创建GO/AO对象
2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
3.将实参值和形参统一

4.在函数体里面找函数声明,值赋予函数体
在这里插入图片描述

以此为例:

再次函数中我们来进行预编译:
1.创建AO对象:我们隐式的在函数中创建了一个AO的对象来盛放函数中的变量,此时对象中并没有值;

2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined:我们在第二个过程中需按照变量和形参
在这里插入图片描述

3.将实参值和形参统一:此时将实参带入函数中由于在函数外 f(1),因此AO中a = 1
在这里插入图片描述

4.在函数体里面找函数声明,值赋予函数体:由于在函数中有 function a() {} ,这一函数因此此时AO中 a = function a() {}
在这里插入图片描述

在进行完预编译后此时若执行函数则会以AO为基础对函数中的变量进行赋值:此时函数中有两次打印一次在函数开头,一次在函数为a赋值之后

再赋值前由于AO中值不变因此a所打印出的值为 function a() {}

在赋值后AO中a = 123,所以此时打印出的值为123。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值