ES6新增了两个重要的关键字let和const,相信大家都不陌生,但是包括我在内,在系统学习ES6之前也只使用到了【不存在变量提升】这个特性。

let声明一个块级作用域的本地变量

const语句声明一个块级作用域的本地常量,不可以重新赋值

支持块级作用域
var定义的变量会提升到整个函数作用域内,let/const则支持块级作用域。

块级作用域: 由{}包裹的作用域(函数那种{}不算)

来看一个var的例子:

{  var a = 1;}console.log(a);

此时输出1,因为var没有块级作用域。

来看一个let的例子(const效果一样):

{  let a = 1;}console.log(a);

此时会报错ReferenceError,因为let/const支持块级作用域,所以let定义的a只在{}可以访问

不存在变量提
与var不同的是,let/const声明的变量不存在变量提升,也就是说{}对于let/const是有效的。

来看一个var的例子:

console.log(a);var a = 1;

此时会输出undefined,因为var声明的变量会提升到作用域顶部(只提升声明,不提升赋值)

来看一个let的例子(const效果也一样):

console.log(a);let a = 1;

此时会报错ReferenceError,因为let不存在变量提升

同一作用域内不可以重复声明
同一作用域内let/const不可以重复声明,var可以。

来看一个var的例子:

var a = 1;var a = 2;console.log(a);

此时会输出2,var是支持重复声明的,后面声明的值会覆盖前面声明的值。

来看一个let的例子(const效果也一样):

let a = 1;let a = 2;console.log(a);

此时会报错SyntaxError,因为同一作用域内let/const不可以重复声明。

再来看一个不同作用域的例子:

let a = 1;{  let a = 2;}console.log(a);

此时输出1,因为两者作用域不同

暂存死区
暂存死区TDZ(Temporal Dead Zone)是ES6中对作用域新的语义。

通过let/const定义的变量直到执行他们的初始化代码时才被初始化。在初始化之前访问该变量会导致ReferenceError。该变量处于一个自作用域顶部到初始化代码之间的“暂存死区”中。

来看以下例子:

function do_something() {  console.log(bar); // undefined  console.log(foo); // ReferenceError  var bar = 1;  let foo = 2;}do_something();

var定义的变量声明会提升到作用域顶部,所以bar是undefined,而let定义的变量从作用域开始到let foo=2这中间都无法访问,访问会报错ReferenceError

暂存死区与typeof
typeof检测var定义的变量或者检测不存在的变量时会返回undefined,如果检测暂存死区内的变量,会报错ReferenceError.

console.log(typeof foo); // undefinedconsole.log(typeof bar); // ReferenceErrorconsole.log(typeof bar2); // undefinedlet bar = 1;var bar2 = 2;

也就是说typeof去检测未初始化的let变量时会报错,var或者未声明的变量不会报错

面试题

function test(){   var foo = 33;   {      let foo = (foo + 55);   }}test();

以上函数执行结果是什么?为什么?

报错

{}内有let定义的foo,所以存在暂存死区,(foo + 55)这个表达式是在let foo之前执行的(赋值时先执行等号右边的,执行完毕把结果赋给等号左边),表达式执行的时候还没有初始化foo,所以报错ReferenceError

总结

  • let/const支持函数作用域和块级作用域,var只有函数作用域

  • let/const不存在变量提升,var存在变量提升

    • let/const同一作用域内不可以重复声明,var可以重复声明
  • let/const存在暂存死区,var不存在

面试题

let b = 1;function test4() {    console.log(b);    let b = 2;}test4()
©著作权归作者所有:来自51CTO博客作者mob604756eccc76的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. js三 作用域与闭包,继承
  2. 【shell】shell脚本实战-awk工作模式讲解
  3. 【DB笔试面试389】在Oracle中,什么是绑定变量窥探?
  4. 【Linux】shell脚本基础-变量
  5. js基础知识:变量与常量,函数及参数
  6. 0402作业
  7. 【11g新特性】DDL_LOCK_TIMEOUT的作用
  8. 不产生第三个临时变量的前提交换两组数据
  9. JavaScript 之 作用域和闭包,类的继承

随机推荐

  1. android 扫描SD卡与系统文件(转)
  2. android搭建环境错误 daemon not running
  3. Eclipse 卡死在 Android SDK Content Loa
  4. Android有效解决加载大图片内存溢出问题
  5. 屏蔽警告: WARNING: EmulatorService.cpp:
  6. Android 中文 API 文档 (44) ―― Chronome
  7. android 控件xml属性
  8. Android调试工具 adb
  9. android Linearlayout中有关gravity与lay
  10. 【Arcgis for android】保存地图截图到sd