let变量提升问题

来源:互联网 发布:手机虚拟歌姬软件 编辑:程序博客网 时间:2024/06/08 17:50
之前通过babel-node将es6转为es5后结合生成的es5代码认为let是在es5的基础上封装的语法糖,并且通过babel-node执行没有报ReferenceError而认为其有变量提升,其实这是错误的,let是es中新加入的一个标识符而已。并且没有变量提升。特此勘正。

  1、let中没有变量提升。

  在通过babel-node执行es6的代码时,是将es6转换为es5后去执行的,所以下面的代码

[html] view plain copy
  1. <span style="font-size:18px;">if (true) {  
  2.   // TDZ开始  
  3.   tmp = 'abc'; // ReferenceError  
  4.   console.log(tmp); // ReferenceError  
  5.    
  6.   let tmp; // TDZ结束  
  7.   console.log(tmp); // undefined  
  8.    
  9.   tmp = 123;  
  10.   console.log(tmp); // 123  
  11. }<br>  转换为es5后的代码为</span>  



[html] view plain copy
  1. <span style="font-size:18px;">if (true) {  
  2.      
  3.     _tmp = 'abc'; //  
  4.     console.log(_tmp); // abc  
  5.    
  6.     var _tmp = undefined;  
  7.     console.log(_tmp); // undefined  
  8.    
  9.     _tmp = 123;  
  10.     console.log(_tmp); // 123</span>  


  并且输出的是undefined,而不是ReferenceError,但是在这里就不要认为let存在变量声明,babel-node在执行的过程中会将代码转为es5,

但是在正式的es6环境下会输出ReferenceError,  和var声明的变量不一样,var 是当一个变量所在的函数被解析的时候,就为函数创建了一个

函数作用域,变量也被初始化为undefined,然后当函数执行到该变量声明的地方的时候,就会对该对象进行初始化,如果没有赋值,那么该变量

的值就是undefined。而let声明的变量存在TDZ(The temporal dead zone) 什么意思呢?当let所在的包含块被解析时,会创建一个块级作用

域,但是此时变量是没有初始化,在该块级作用域中尝试在let声明之前获取它的值或者给它赋值都将会报ReferenceError的错误。当执行到let

声明的变量的时候会对该变量进行初始化,如果没有赋值,那么该变量的值是undefined。在这里要感谢WhatTheFsck的指点。