塊級做用於對於強類型語言經驗的人應該很是好理解, 一言以蔽之:ES5對變量做用於分隔使用了函數(詞法做用域), 而ES6使用花括號(塊做用域)。
對於詞法做用域在 javascript函數、做用域鏈與閉包 中有詳細的解釋。對於let 和 const聲明的變量在花括號的分割下一樣會造成做用於鏈(內部訪問外部的, 但外部不能訪問內部)。可是花括號對於沒有聲明直接定義以及用 var 聲明的變量沒有影響, 這些變量依然遵照詞法做用域規則。javascript
對於let 和 const 最大的好處就是避免了可能的運行時錯誤, 不過也有直觀的好處:java
//用塊(Blocks)替換當即執行函數(IIFEs) //ES5 (function () { var food = 'Meow Mix'; }()); console.log(food); // Reference Error //ES6 { let food = 'Meow Mix'; } console.log(food); // Reference Error
var a = []; for(let i = 0; i < 10; i++){ a[i] = function(){ console.log(i); } } a[6](); //這裏輸出6, 在var定義i的for循環中輸出 10 console.log(i); //ReferenceError
function b(){console.log("outside");} function f(){ if(false){ function b(){console.log("inside");} } b(); } f(); // ES5 中報錯:"TypeError:b is not a function" 而 ES6 中輸出"outside"
由此例能夠看出 function 定義函數不具備塊級做用域。c++
但咱們須要注意的一下幾點:segmentfault
var a = 10; let b = 20; const c = 30; console.log(window.a); //10 console.log(window.b); //undedined console.log(window.c); //undedined
var temp = 20; (function area(){ console.log(temp); //undefined var temp = 30; //聲明提早 }()); if(true){ console.log(temp); //ReferenceError 可是 babel 會獲得 undefined let temp = 20; }
//一個隱蔽的死區 function bar(x = y, y = 2){ console.log(x, y); } bar(); //報錯, 由於定義 x 的時候, y 尚未定義 (babel 中不報錯,獲得 undefined 2) function par(x = 2, y = x){ console.log(x, y); } par(); //22
let a = 10; var b = 20; const c = 30; let a = 4; //報錯 const b = 3; //報錯 c = 20; //報錯, c是隻讀的
let a=b=3; //報錯 b 未定義 const c=d=2; //報錯 d 未定義
var f; { f = function(){ console.log("inside"); } } f();
const 這個特性和底層的 c++ 一致, 在 c++ 中 const 至關於常指針 int * const p
, 也就是其指向的數據所在內存區域可讀可寫, 可是指針的值初始後就不能改。babel
const a = 10; const b = { num: 20 }; b.num = 30; console.log(b.num); //30 a = 20; //TypeError b = { num: 90 }; //TypeError
若是想讓非基本變量內部也不可改變, 須要使用 Object.freeze()
方法。能夠參考:javascript對象、類與原型鏈閉包
對於跨模塊的常量, 能夠這樣寫:ide
// const.js module export const A = 1; export const B = 2; // test.js 文件 import * as constants from './const'; console.log(constants.A); //1 console.log(constants.B); //2 //or import {A, B} from './const'; console.log(A); //1 console.log(B); //2