块级做用于对于强类型语言经验的人应该很是好理解, 一言以蔽之: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