zoukankan      html  css  js  c++  java
  • 【JavaScript】变量提升和函数提升

    <script> 
        console.log(a);
        var a = "a";
        function foo() {
            console.log(a); 
            var a = 'a1'; 
        } 
        foo(); 
    </script>

    由于js自上而下逐行解释执行的,有人可能会认为第一行代码引用了一个没有声明的变量a,会抛出 ReferenceError  异常,而注掉第一行后,由于变量 a 在第二行log之前已经声明并赋值,打印结果应该是 "a"。而实际的执行结果是:

    在js代码执行前引擎会先进行预编译,预编译期间会将变量声明与函数声明提升至其对应作用域的最顶端。举例来说:

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

    变量提升

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

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

    函数提升

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

    <script> 
        console.log(foo1); 
        foo1(); 
        console.log(foo2); 
        foo2(); 
        function foo1 () {
            console.log("foo1");
        };
        var foo2 = function () {
            console.log("foo2");
        }; 
    </script>

    即函数提升只会提升函数声明,而不会提升函数表达式,再举一个小例子:

    <script> 
        var a = 1;
        function foo() {
            a = 10;
            console.log(a);
            return;
            function a() {};
        }
        foo();
        console.log(a);
    </script>

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

    <script> 
        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 
    </script>

    变量提升和函数提升的顺序

    在作用域中,不管是变量还是函数,都会提升到作用域最开始的位置。不同的是,函数的提升后的位置是在变量提升后的位置之后的。

    <script> 
       function foo() {
            console.log(a);
            var a = 1;
            console.log(a);
            function a() { }
            console.log(a);
        }
        foo();
    </script>

    上面的代码在js眼中是这样解析的:

    <script>  
        function foo() {
            var a;
            function a() { }
            console.log(a);  
            a = 1;
            console.log(a);  
            console.log(a);  
        }
        foo();
    </script>

    注意:只有声明的变量和函数才会进行提升,隐式全局变量不会提升。例:

    <script> 
        function foo() {
            console.log(a);
            console.log(b); // 报错
            b = 'aaa';
            var a = 'bbb';
            console.log(a);
            console.log(b);
        }
        foo();
    </script>

    参考链接:

    https://blog.csdn.net/kontar123/article/details/83508740

    https://www.cnblogs.com/lvonve/p/9871226.html#1589567655

  • 相关阅读:
    @XmlAccessorType @XmlType 详解
    eclipse properties 文件查看和编辑插件 Properties Editor
    对象设计解耦的方法IOC和DI
    J2EE7与Servlet3.x
    关于maven
    Spring版本功能变更&Spring4.x的新特性
    2017第37周三
    Java线程池
    Java并发包
    Java内部类
  • 原文地址:https://www.cnblogs.com/zhaoyl9/p/14657223.html
Copyright © 2011-2022 走看看