• 关于变量提升


      我们在写js函数的时候,一般情况下,会避免变量重名,以及变量和函数重名的情况,所以很少会涉及到变量提升的概念。

      变量提升都是发生在js预编译过程中的,能够完全理解变量提升,有利于我们彻底弄懂js的概念。

            var a = 1;
    
            function test(a) {
                console.log(a)
                var a = 12;
    
                function a() {}
                console.log(a)
            }
            test(34)    
    

      在我们的面试过程中,如果存在笔试,那么少不了类似于这种题目。那么这么倒题目,其中两个console.log(a)究竟打印出来的是什么呢?看结果:

     

      那我们怎么理解这种提升,以及这些提升的规则又是什么呢?

      在预编译过程中,我们可以这么理解:

      系统首先创建一个对象,假设为[[AO]],然后查找形参和声明变量,作为该对象的属性,其值为undefined;然后将形参的值和实参的值统一,也就是把[[AO]]对象当中属性为形参的值赋值,如果传递了实参,那么这时候修改属性值为实际参数值;最后在函数体内查找函数声明,值为函数体。

      在上述例子中的第一个console.log(a)的位置,如果函数体内没有函数声明function a (){},那么这里打印出来的值为实际参数值34。

      当预编译结束之后,各种变量赋值也好,函数赋值也好,都是重新修改该对象内属性的值,运行到哪一步,就在哪一步修改。

      确认一点,变量提升,只适用于var定义的变量。

      如果使用let或者const定义变量,那么就不存在上述各种规则。将上述代码稍作修改:

            var a = 1;
            function test(a) {
                console.log(a)
                let a = 12;
                function a() {}
                console.log(a)
            }
            test(34)    
    

      唯一变动,就是在函数体内部声明变量时,使用let声明替换了之前的var声明,如果此时再次运行的话,就会发现:报错了!

      

      提示为请确认a是否已经声明。这是因为函数体内使用了let声明变量,但是在声明之前就开始调用了该变量,导致报错。

      在阮一峰老师的书《ECMAScript 6 入门》中说到:

    只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
    

      这就是所谓的暂时性死区。在暂时性死区内,不仅无法提前使用let声明的变量,他也不会获取函数体外部作用域内的同名变量。这就是我们例子中所展示的即使外部和形参名称均为a,我们在函数体内部也不能先使用a变量。暂时性死区会到该变量被声明后结束。

      如果希望了解更多,请参考阮一峰老师所述的“暂时性死区”。

      那就可以总结一下:

      1、只有var定义的变量存在变量提升这一说法,而且必然会发生变量提升。

      2、变量提升和函数提升的过程:

        1)先找var定义的变量和形参: a--> undefined

        2)实参和形参统一

        3)函数声明提升(仅仅函数声明,函数表达式是不存在提升一说的)

      3、如果块级作用域内出现let或者const定义的变量,而且在该变量定义之前使用了,那么必然报错。

        

      

  • 相关阅读:
    IDEA中代码无故报红解决方法
    CAP原则的基本理论知识
    Java IO 拷贝MP3文件,包括递归子文件夹下的文件
    maven 配置阿里云镜像 settings.xml内容
    Restful API 级别及意义
    日常巡检(脚本)
    使用Matplotlib画图系列(一)
    Python 阶乘factorial
    交叉验证思想
    FeatureSelectors
  • 原文地址:https://www.cnblogs.com/zhuhuoxingguang/p/10370037.html
Copyright © 2020-2023  润新知