ES6文档学习系列的学习文档均出自ES6官方文档
let和const命令
let
不存在变量提升
暂时性死区
只要块级作用域内存在let
命令,它所声明的变量不再受外部影响,且该变量在let
声明后使用
不允许重复声明
let
不允许相同作用域内声明相同变量
function f () {
var a = 10
let a = 10 // error
}
function f () {
let a = 10
let a = 11 // error
}
let
不允许在函数内部重复声明参数变量
function f (arg) {
let arg = 10 // error
}
块级作用域
引入原因:
- 内层变量可能覆盖外层变量
var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = "hello world"; } } f(); // undefined
- 用来计数的循环变量可能泄漏为全局变量
var s = 'hello'; for (var i = 0; i < s.length; i++) { console.log(s[i]); } console.log(i); // 5
主要特点
- ES6允许块级作用域任意嵌套
- 外层作用域无法读取内层作用域变量
- 内层作用域可以声明外层作用域的同名变量
块级作用域与函数声明
ES6规定,块级作用域内,函数声明语句的行为类似let
,在块级作用域之外不可引用
do表达式
do表达式实现块级作用域转变为表达式,即可以返回值
let x = do {
let t = f();
t * t + 1;
};
const命令(定义常量)
-
不能改变const常量值
const a = 3; a = 5; // TypeError: Assignment to constant variable.
-
声明即要初始化
const foo; // SyntaxError: Missing initializer in const declaration
-
声明所在的块级作用域内有效
if (true) { const MAX = 5; } MAX // Uncaught ReferenceError: MAX is not defined
-
存在暂时性死区
if (true) { console.log(MAX); // ReferenceError const MAX = 5; }
-
对于复合型变量,const命令只保证变量名指向的地址不变,不保证该地址的数据不变
const foo = {}; foo.prop = 123; foo.prop // 123 foo = {}; // TypeError: "foo" is read-only
const a = []; a.push('Hello'); a.length = 0; a = ['Dave']; // error
-
不可重复声明
顶层对象的属性
顶层对象,浏览器环境指window对象,node指global对象。
在ES5中,顶层对象的属性与全局变量是等价的
window.a = 1;
a // 1
a = 2;
window.a // 2
问题:
- 当全局变量是顶层对象的属性创造时,无法在编译时报出变量未声明的错误,只有运行时才能知道(属性创造时动态的)
- 程序员很容易在不知不觉中创建全局变量
- 顶层的属性可随处读写,不利于模块化编程
- 顶层对象作为一个有实体含义的对象是不合适的,如window对象有实体含义,指浏览器的窗口对象
改变:
ES6规定:
- var命令和function命令声明的全局变量,依旧是顶层对象的属性
- let、const、class命令声明的全局变量,不属于顶层对象的属性
var a = 1;
// 如果在Node的REPL环境,可以写成global.a
// 或者采用通用方法,写成this.a
window.a // 1
let b = 1;
window.b // undefined
global对象
在所有环境下,global都是存在的,都可以从它拿到顶层对象
// ES6模块的写法
import getGlobal from 'system.global';
const global = getGlobal();