ES6 块级作用域

var 变量提升

  • 全局作用域下自动转换为window对象属性,而let、const不会。
function test1() {
  console.log(a) // undefined
  if(false) {
    var a = 1;
  }
  console.log(a) // undefined
  function inner() {
    if(false) {
      var b = 2
    }
  }
  console.log(b); //RefrenceError b is not defined
}

示例:http://jsbin.com/tunonipare/edit?html,js,console

let 块级作用域

  • 可以读取外层变量、可以重新定义外层变量,但是不能在块级作用域内重新声明函数如果必须要使用函数表达式声明。块级作用域声明函数必须在大括号内。
function test() {
  let a = 1;
  if(true) {
    let b = 2;
  }
  console.log(a); // 1
  console.log(b); // b is not defined
}
test();

for(var i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(`1: ${i}`); // 5 5 5 5 5
  }, 0);
  
  (function(i) {
    setTimeout(() => {
      console.log(`2: ${i}`) // 0 1 2 3 4
    }, 0);
  })(i);
}
console.log(i);

for(let j = 0; j< 5; j++) {
  setTimeout(() => {
    console.log(`3: ${j}`) // 0 1 2 3 4
  }, 0);
}
console.log(j); // j is not defined

示例:http://jsbin.com/tatahor/28/edit?js,console

  • 暂时性死区:只要块级作用域内有let命令,它声明的变量就绑定了该区域,不受外部变量影响。
var tmp = [];
var obj = {a: 1};
if(false) {
    obj.b = 2;
    typeof obj; // undefined;
    tmp = 1; // RefrenceError: tmp is not defined;
    typeof tmp; // RefrenceError: tmp is not defined;
    let tmp = 1;
}
console.log(tmp) // []
console.log(obj) // {a: 1, b: 2};

function(a = b, b = 1) { // RefrenceError: b is not defined
    console.log(a + b);
}
function(a = 1, b = a) { // success
    console.log(a + b);
}

示例:http://jsbin.com/qazarod/14/edit?js,console

const 常量

  • 常量必须初始化赋值,不可更改。
const type = "ACTION";
type = 1; // error
console.log(type);

const obj = {
  a: 1,
  b: 2
}
obj.a = 2;
delete obj.b
console.log(obj); // {a: 2}

示例:http://jsbin.com/coxudin/4/edit?js,console

最佳实践

  • 默认使用const,只有需要改变时才用let防止变量被错误修改。

转载请注明出处