变量、函数申明晋升

其中有一个特点为: 函数会将代码块全副晋升,而变量只会申明晋升,不会将赋值解析到头部。
console.log(a);var a = 1;var b = 2;console.log(a);function a() {};

下面代码的解析形式为

var a;var b;function a() {};console.log(a);// ƒ a() {}a = 1;b = 2;console.log(a);// 1;

let,const

es6减少了块级作用域,而 letconst 定义的变量只在它所在的代码块无效,都不存在变量晋升。

let

没有变量晋升

{    console.log(a);// ReferenceError: Cannot access 'a' before initialization    let a = 1;}{    console.log(a);// undefined    var a = 1;}

因而也呈现了新的问题

// es5的状况var demo = 1;if (true) {    demo = 2;    // ReferenceError    let demo;}

var 定义的全局变量 demo 在进入 if 区域块时又被 let 从新定义了,所以在 iflet 之前应用demo都是会报错的。这个报错的局部就是暂时性死区(temporal dead zone,简称TDZ)。

在es6之前 *typeof 相对平安的,即便是一个没定义的变量也会输入“undefined“,在es6中就不再是百分百白平安。
{    typeof(age);    // undefined}{    typeof(age);    // ReferenceError    let age = 1;}

const

const 个性与 let 类似,不存在变量晋升,之作用于存在的代码块中,也会呈现暂时性死区。
不同点在与 const 申明的变量不能扭转值,实质是不能扭转指向的地址的值。

// 简略数据类型const cs = 1;cs = 2// TypeError: Assignment to constant variable.// 简单数据类型const cs2 = {a:1, b:2}cs2.a = 2// print cs2// {a: 2, b: 2}a: 2b: 2__proto__: Objectcs2 = {}// TypeError: Assignment to constant variable.

如果想要一个简单数据类型内容固定可应用办法 Object.freeze(obj) ,扭转变量不会报,然而内容不会变动。

// print cs2// {a: 2, b: 2}Object.freeze(cs2)// modify cs2 cs2.a = 3// print cs2 // {a: 2, b: 2}

块级作用域中的函数申明

因为版本兼容问题,当初在块级作用域中申明的函数能够不恪守es6的规定,有本人的行为形式。

  • 容许在块级作用域内申明函数。
  • 函数申明相似于 var, 会晋升到全局作用域或函数作用域的头部。
  • 同时,函数申明还会晋升到所在的块级作用域头部。
// es5function f() { console.log('I am outside!'); }(function () {  if (false) {    // 反复申明一次函数f    function f() { console.log('I am inside!'); }  }  f();}());// print I am inside!// es6// print TypeError

上述代码在es6中的真正解析形式为如下代码

// 浏览器的 ES6 环境function f() { console.log('I am outside!'); }(function () {  // 把函数晋升为 var 变量  var f = undefined;  if (false) {    function f() { console.log('I am inside!'); }  }  f();}());
本文用于自己常识记录与温习,借鉴原文为阮一峰的 ES6 入门教程