• JS变量声明提升


    一、作用域

       JS中,作用域为function内的区域,称为函数作用域。

    二、变量声明

      在ES6之前,通过var声明一个变量,但是ES6之后,又添了两个关键词来声明变量:let和const

      var:声明了一个变量,这个变量的作用域是当前执行的上下文

      let:声明了一个块级域的局部变量,并且它声明的变量只在所在的代码块内有效

      const:声明了一个只读的块级域的常量,并且它声明的变量只在所在的代码块内有效

     1 { // 代码块
     2   var a = 1;
     3   let b = 2;
     4   const c = 3;
     5   
     6   console.log(a);   // 1
     7   console.log(b);   // 2
     8   console.log(c);   // 3
     9 }
    10 
    11 console.log(a);   // 1
    12 console.log(b);   // 报错,ReferenceError: b is not defined(…)
    13 console.log(c);   // 未执行, 因为上面语句出错,所以这条语句不再执行,如果上面的语句不报错,那么这里就会报错
     1 (function (){
     2   var a = 1;
     3   let b = 2;
     4   const c = 3;
     5   
     6   console.log(a);   // 1
     7   console.log(b);   // 2
     8   console.log(c);   // 3
     9 })();   // 为了方便,这里使用了自执行函数
    10 
    11 console.log(a);   // 报错,ReferenceError: a is not defined(…)
    12 console.log(b);   // 未执行
    13 console.log(c);   // 未执行

      let和const不像var那样,会发生变量提升现象

    1 console.log(a);    // 报错,ReferenceError: a is not defined
    2 let a = 2;
    3 console.log(a);    // 待执行

    ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

    三、变量声明提升

    JS在执行前会对整个脚本文件的声明部分做完整解析(包括局部变量),从而确定变量的作用域。

      当局部变量与全局变量重名时,局部变量的范围会覆盖全局变量的范围。当离开局部变量的范围后,又回到全局变量的范围。

     1             var a=1;
     2             function test(){
     3                 alert(a);  //undefined  此处a并不是全局变量,函数里面已经声明了一个重名的局部变量,所以全局变量会被覆盖,JS执行前会对声明部分解析,所以此处的a只是声明但未赋值
     4                 a=4;       //此处a被赋值
     5                 alert(a);  //4 ,此处a仍是局部变量
     6                 var a;     //局部变量a在这里声明
     7                 alert(a);  //4  
     8             }
     9             test();
    10             alert(a);      //1,此处a为全局变量
    1     var a=10;
    2         function test(){
    3             a=100;
    4             alert(a);        //100  此处a为局部变量,如果没有第三行a=100,此处则为undefined,有了第三行,此处局部变量被赋值为100
    5             alert(this.a);   //10   函数内部的this指向的是函数调用者,在这里函数是被全局对象调用,所以此处的this指向全局对象(这里指window)
    6             var a;
    7             alert(a);        //100   /局部变量100
    8         }
    9         test()

    在基本的语句(或者说代码块)中(比如:if语句for语句while语句switch语句for...in语句等),不存在变量声明提升

    四、函数声明提升

    函数声明和函数表达式在语法上是等价的,但有一点不同,函数声明会被提到作用域顶部,而函数表达式不会。

     1 fun();       // hello 
     2 
     3 function fun(){
     4   console.log("hello");
     5 }
     6 
     7 // --------------
     8 // 提升后
     9 
    10 function fun(){
    11   console.log("hello");
    12 }
    13 
    14 fun();       // hello 
     1 fun();       // 报错,TypeError: fun is not a function
     2 
     3 var fun = function(){
     4   console.log("hello");
     5 };
     6 
     7 // --------------
     8 // 提升后
     9 
    10 var fun;
    11 
    12 fun();        // 报错,TypeError: fun is not a function
    13 
    14 fun = function(){
    15   console.log("hello");
    16 };
  • 相关阅读:
    JS条件判断小技巧
    简单实现节流函数和防抖函数(转载)
    一篇常做错的经典JS闭包面试题
    前端冷知识集结
    闭包
    仔细认识setInterval
    仔细认识setTimeout
    单方向指定时间内的匀速运动
    图片延迟加载
    优化网页上的gif
  • 原文地址:https://www.cnblogs.com/endlessmy/p/8409951.html
Copyright © 2020-2023  润新知