OPY-bbt/OPY-bbt.github.io

ES6-let const

Opened this issue · 4 comments

ES6-let const

let

块作用域

{
  let a = 10;
  var b = 1;
}
a; // ReferenceError: a is not defined.
b;

babel 之后

"use strict";

{
  var _a = 10;
  var b = 1;
}
a;
b;

不存在变量名提升

var 和 let、const 的不同之处在于后两者是在编译时才初始化,所以会存在死区。

暂时性死区(temporal dead zone)

var tmp = 123;
if (true) {
  tmp = 1; // referenceError
  let tmp;
}

值得注意的typeof运算符在碰到死区时,也会报referenceError,如果一个变量没有被声明,反而不会报错

不允许重复声明

为什么需要块级作用域

var tmp = new Date();

function f() {
  console.log(tmp); // undefined
  if (false) {
    var tmp = 'hello world';
  }
}

f();

块级作用域内声明函数

函数声明类似于var,即会提升到全局作用域或函数作用域的头部。

// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }

(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }

  f();
}());
// Uncaught TypeError: f is not a function
// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }
(function () {
  var f = undefined;
  if (false) {
    function f() { console.log('I am inside!'); }
  }

  f();
}());
// Uncaught TypeError: f is not a function

const

const A = 1;
A = 2;

// after babel
"use strict";

function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); }

var A = 1;
A = (_readOnlyError("A"), 2);

顶层对象

浏览器里是window,Node里是global。ES5中顶层对象和全局变量是等价的。
从ES6开始顶层对象和全局变量脱钩。但是为了保持兼容性。var、function声明的还是顶层对象属性。let、const、class声明的全局变量不属于顶层对象的属性。

var a = 1;
// 如果在 Node 的 REPL 环境,可以写成 global.a
// 或者采用通用方法,写成 this.a
window.a // 1

let b = 1;
window.b // undefined

值得注意的是,babel没有实现这个特性

let b = 1;
console.log(window.b);

// after babel
"use strict";

var b = 1;
console.log(window.b);