美文网首页
js中的变量提升和函数提升

js中的变量提升和函数提升

作者: Xindot | 来源:发表于2021-08-06 10:18 被阅读0次
    console.log(a);
    var a = "a";
    var foo = () => {
        console.log(a);
        var a = "a1";
    }
    foo();
    //输出结果
    undefined
    undefined
    
    console.log(a);
    var a = "a";
    var foo = () => {
        console.log(a);
        a = "a1";
    }
    foo();
    //输出结果
    undefined
    a
    

    对比上面2端代码

    一、什么是提升(Hosting)?

    引擎会在解释JavaScript代码之前首先对齐进行编译,编译过程中的一部分工作就是找到所有的声明,并用合适的作用域将他们关联起来,这也正是词法作用域的核心内容。
    简单说就是在js代码执行前引擎会先进行预编译,预编译期间会将变量声明与函数声明提升至其对应作用域的最顶端。举例来说:

    console.log(a);
    var a = 3;
    //预编译后的代码结构可以看做如下
    var a; // 将变量a的声明提升至最顶端,赋值逻辑不提升。
    console.log(a); // undefined
    a = 3; // 代码执行到原位置即执行原赋值逻辑
    

    二、变量提升

    变量声明的提升是以变量所处的第一层词法作用域为“单位”的,即全局作用域中声明的变量会提升至全局最顶层,函数内声明的变量只会提升至该函数作用域最顶层。那么开始的一段代码经过预编译则变为:

    var a;
    console.log(a); // undefined
    a = "a";
    var foo = () => {
       var a; // 全局变量会被局部作用域中的同名变量覆盖
       console.log(a); // undefined
       a = "a1";
    }
    foo();
    

    输出undefined就很明了。

    ES6新增了let和const关键字,使得js也有了“块”级作用域,而且使用let和const 声明的变量和函数是不存在提升现象的,比较有利于我们养成良好的编程习惯。

    三、函数提升

    有了上面变量提升的说明,函数提升理解起来就比较容易了,但较之变量提升,函数的提升还是有区别的。举例说明:

    console.log(foo1); 
    foo1(); 
    console.log(foo2); 
    foo2(); 
    function foo1 () {
        console.log("foo1");
    };
    var foo2 = function () {
        console.log("foo2");
    };
    // [Function: foo1]
    // foo1
    // undefined
    // TypeError :foo2 not a function
    

    即函数提升只会提升函数声明,而不会提升函数表达式。

    再举一个小例子:

    var a = 1;
    function foo() {
        a = 10;
        console.log(a);
        return;
        function a() {};
    }
    foo();
    console.log(a);
    直接上结果:
    10
    1
    

    上面的代码块经过预编译后可以看做如下形式(只分析foo方法内部情况):

    var a = 1; // 定义一个全局变量 a
    function foo() {
        // 首先提升函数声明function a () {}到函数作用域顶端, 然后function a () {}等同于 var a =  function() {};最终形式如下
        var a = function () {}; // 定义局部变量 a 并赋值。
        a = 10; // 修改局部变量 a 的值,并不会影响全局变量 a
        console.log(a); // 打印局部变量 a 的值:10
        return;
    }
    foo();
    console.log(a); // 打印全局变量 a 的值:1
    

    ————————————————
    版权声明:本文为CSDN博主「kontarK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/kontar123/article/details/83508740

    相关文章

      网友评论

          本文标题:js中的变量提升和函数提升

          本文链接:https://www.haomeiwen.com/subject/gbsbvltx.html