「javscript-预编译」

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

例如:bash

var a = 10 ;
闭包

add()函数

function add() {    ui

    return  a + b;spa

};code

var b = 1;cdn


结果输出NaN ;blog

这就很使人头疼,下面咱们来解释下为何会出现这种状况吧。three

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  

固然还能够在难一点,但是楼主飞机误点了,一直在等飞机😭  深圳这该死的 ☁️ 

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

相关文章
相关标签/搜索