欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript函数的预解析

程序员文章站 2022-04-19 13:33:59
JavaScript函数的预解析先聊聊什么是预解析举几个栗子例1:例2:例2(改):先聊聊什么是预解析预解析指的就是函数的编译和执行的过程,js是一个解释型的语言,就是在代码执行之前,先对代码进行通读和解释,然后再执行代码。也就是说js运行前会有两个步骤:#1:解释代码:因为是在所有代码执行之前进行解释,所以叫做预解析(预解释)。预解析的内容只要有两个:a:声明式函数1):声明式函数,指的是function f1() {要执行的代码;}仅仅是声明式函数,像赋值式函数就不属于要预解析的内容...

先聊聊什么是预解析

预解析指的就是函数的编译和执行的过程,js是一个解释型的语言,就是在代码执行之前,先对代码进行通读和解释,然后再执行代码。也就是说js运行前会有两个步骤:
#1:解释代码:
因为是在所有代码执行之前进行解释,所以叫做预解析(预解释)。
预解析的内容有两个:
a:声明式函数
1):声明式函数,指的是function f1() {
要执行的代码;
}
仅仅是声明式函数,像赋值式函数就不属于要预解析的内容了。
(什么是赋值式函数?简单说一下就是指用var 一个变量等于一个函数的方法创建的一个函数:var f1= function () {要执行的代码;})
b:var关键字
在内存中声明有一个变量名。

#2:然后才是执行代码。

举几个栗子

例1:

fn();//'我是fn函数'
console.log(num);//undefined

 function fn(){
    console.log('我是fn函数')
}
var num = 100;

咱们来看看这一段简单代码是要怎么解析的:
根据咱们上面所说:先找出声明式函数和var关键字命名的变量,然后将之提前至最前面,然后再是执行代码。

//第一阶段预解析:将下面代码提至最前面
 function fn(){
        console.log('我是fn函数')
    }
    var num ;

//第二阶段代码执行:
 fn();//'我是fn函数'
 console.log(num);//undefined
 num = 100;//这里才会赋值
 
 //按照这个顺序运行下来

*这里有个点要注意下:
我们的var关键字在预解析阶段只是声明变量,而不进行赋值,赋值是在第二阶段代码执行时才会进行赋值。因此是将声明式函数和声明变量提前至代码运行的最前面。

综合一二阶段按顺序执行我们可以看到:
先是声明了一个fn的函数,然后var了一个变量num,但是并没有赋值,接着运行下去是调用函数fn(),执行函数时就会打印函数里的“我是fn函数”,然后是打印num值,由于此时的num仅仅是var声明了还没赋值所以会打印undefined,然后在给num赋值。

例2:

上面那个简单例子看懂了的话咱们可以再看一个难一点的,这个要是也会了那预解析相信你也基本掌握该怎么分析了,话不多说咱们上代码。
先看看不注释f1里面的console.log(b)和console.log(c )

f1();
    console.log(c);
    console.log(b);
    console.log(a);
    function f1() {
        //函数内部定义的变量只能在函数内部使用
        console.log(a); //undefined
        console.log(b); //试试注释我们吧
        console.log(c); //试试注释我们吧
        var a=b=c= 9;
    }

这一段代码会输出什么呢?
根据上面一题的方法分析咱们同样来看分成两个阶段来做:

这里可以简单提一下全局变量和局部变量:
在函数f1里var a=b=c= 9;就相当于:
var a;声明一个变量;
a=b=c=9;然后给9赋值给c,b,a
此时a有声名为函数f1里面的局部变量外界不可用,b,c未声明会转换成全局变量,外界可以读取到。

进行预解析:
即:

//正确的第一阶段预解析
function f1() {
        //函数内部定义的变量只能在函数内部使用
        var a ; //函数内部再次预解析,将var a;提前
        console.log(a); //undefined
        console.log(b); //未定义b,报错,后续就不会继续执行下去了
        console.log(c); //
        a=b=c= 9;
    }

//第二阶段代码执行
f1();
console.log(c);
console.log(b);
console.log(a);

咱们先对函数里面的这里部分分析:
var a ;声明了a变量,咱们就可以打印出来a,由于赋值是在打印之后所以打印结果为undefined,然后此时console.log(b)和console.log(c ),这两个都还没var声明定义所以会直接打印会报错(报错结果为:Uncaught ReferenceError: b is not defined意思就是b还没定义,只要有一个报错后面就不会继续执行了),所以也就不需要继续看第二阶段的执行了,到这就报错了。

例2(改):

这个题其实咱们可以在改改,如我上面说的将f1里面的:

 //console.log(b); 试试注释我们吧
 //console.log(c); 试试注释我们吧

这个时候第二阶段就可以继续走下去了,注释后预解析以及执行代码:

function f1() {
        //函数内部定义的变量只能在函数内部使用
        var a ;
        console.log(a); //undefind
        //console.log(b); 
        //console.log(c); 
        a=b=c= 9;
    }
 
 f1();
 console.log(c);//9
 console.log(b);//9
 console.log(a);//报错Uncaught ReferenceError: a is not defined

运行结果为什么会不一样呢?

在函数f1里var a=b=c= 9;就相当于:
var a;声明一个变量;
a=b=c=9;然后给9赋值给c,b,a。
a是函数里用var声明的,是一个局部变量,而b,c没有声明,变量未声明直接赋值,会被转换成全局变量,所以二阶段代码执行时f1里面的a声明了打印时还未赋值,为undefined,外面的c,b由于在里面没有用var声明为全局变量,外部也能读取,所以分别打印9,9,而a是函数里面声明的局部变量,外部不可用,所以a会报错,因为在外部没有定义,更别谈赋值了,相信看到这各位同学对预解析应该理解的也差不多了吧。

本文地址:https://blog.csdn.net/weixin_42649868/article/details/107281616