阅读 158

「javscript-预编译」

众所周知,JavaScript是动态类型语言,比较灵活,常常存在一些令人的头疼的地方。

例如:

var a = 10 ;

add()

function add() {    

    return  a + b;

};

var b = 1;


结果输出NaN ;

这就很令人头疼,下面我们来解释下为什么会出现这种情况吧。

1,JavaScript 语言类型

JavaScript是解释型语言,解释一行执行一行,也可以理解为读取一行执行一行(一行一行执行就对了)

2,预编译阶段

var 申明的变量会存在变量提升过程,函数也会存在这种情况 。提升可以分为全局变量,函数提升,和局部变量,函数提升(⚠️注意,变量提升优于函数提升!)

下面我们来看下题目执行顺序

首先预编译,

变量提升,

var a  = undefind;

var b = undefind;

其次函数提升,

function add () {}

变量函数提升完之后开始计算机系统开始读取代码,第一行,解释一行。

首先执行第一行

var a = undefind ; => var a  = 10;           //解释第一行代码时发现变量被赋值 

add();                                       //解释函数,去找函数

function add () {                            //执行函数内部函数

     return a + b ;                          //此时 a = 10;b = undefind; 

}                                            //结束add()函数,Number ➕ undefind = NaN; 

var b = undefind ; => var b = 1;            //发现变量 b 被赋值

以上就是预编译和JavaScript代码执行顺序的顺序。

好了,下面我们来点面试题吧,相信大家也经常被这些面试题坑。

3,面试题start 

3-1 : 简单使用

var one = 1 ;

var two = 2 ;

function sum () {
    var three =  3 ;  
    
    two = two + three;

    return one + three
};

var newSum = new Sum();

console.log(newSum);复制代码

相信大家看过前面的讲解就会立即可以想到结果, 没错答案是6 ;

我们来看下执行顺序吧。

//首先变量,函数提升

var one = undefind;

var two = undefind;

var newSum = undefind;

function sum() {};

//开始读取并解释JavaScript

var one = undefind => var one = 1;

var two = undefind => var two = 2;

function sum () {
    // ⚠️ 函数内部也会存在变量和函数提升
    var three = undefind; => var three = 3;
    
    /*

        two 被重新赋值,这里还有一个知识点,当函数
        
        内部找不到变量,会向上一层找,一直找到window上,

        如果找不到就是undefined,所以在函数内存查找two

        找不到,会向上一层查找,在全局变量中找到two和one

    */

    two = 2 => two = 2 + 3;    

    return one + two;          //one = 1,two = 2, 输出3

}
//函数sum()的值为3,所以 newSum = 3 ;var newSum = undefind; => var newSum = new sum();  

console.log(newSum);   => console.log(3);  

复制代码

3-2 : 进阶版本

var a = 1;

var b = 2;

function add () {

    var c = 3;

    return a + b;

}

var sum = new add();

console.log(sum);

console.log(c);复制代码

大家可以思考下会打印什么,先来过程吧

//预编译,变量,函数提升

var a = undefind;

var b = undefind;

var sum = undefind;

function add () {};

//读取解释代码

var a = undefind; => var a = 1;

var b = undefind; => var b = 2;

function add () {
    
    var c = undefind;  => var c = 3;

    return a + b ;    =>  1 + 2;

}

var sum = undefind; => var sum = new add(); //var sum = 3;

console.log(sum)   //  3

//这里涉及到一个新知识点,c属于局部变量,全局变量无法访问访问局部变量

//当然有一种方法可以访问,那就是闭包了😄

console.log(c)     //  c is not defind;
复制代码

可能大家还是觉得很简单,那我们在加大难度。


3-3 : 稍高难度版本

var a = 1 ;

var b = 2;

var i = 0;



function add() {
    
    for (;i < b ; i++) {    (function (f) {
            console.log(f)
        })(i)
     };

    return a + i;
}

console.log(i);复制代码

这个算是难度加大版本的了,小伙伴们可以思考下,结果是什么

我们来看下过程

//预编译,变量函数提升 ⚠️ 预编译阶段仅仅只有函数和变量存在提升!

var a = undefind;

var b = undefind;

var i = undefind;

function add() {}

//读取解释JavaScript

var a = undefind; => var a = 1;

var b = undefind; => var b = 2;

var i = undefind; => var i = 0;

function add () {
    //在函数内部无法找到 i 与 b  向上一层查找
    for(;i < b ; i++) {

        //立即执行函数,避免 i 提前变量赋值,

        // 同样用let也可以避免这样的事情发生

        (function(f){
            
            // 立即执行函数和let形成暂时性死区效果一样,依次

            //打印 0 => 1
        
            console.log(f)

        })(i)
    
        //等等,你真的以为执行完了吗?i < b 当这个条件执行完,i被赋值为2,不要忘记这个小细节哦
    }  
  
}

console.log(i);   // i 被重新赋值,打印2复制代码

所以结果依次为 0 ,1 ,2  

当然还可以在难一点,可是楼主飞机误点了,一直在等飞机😭  深圳这该死的 ☁️ 

有更好的面试题的小伙伴可以子啊下面留言告诉我呦,一同进步



关注下面的标签,发现更多相似文章
评论