最近有点时间,于是就想加强我对ES6
的认知,找到了阮老师的《ECMAScript 6 入门》读一下,顺便做一下简记,简记的目的是用最简单的语言来概括出尽量全面的知识点,如果书上的某些话好懂,就直接摘下来,如果难懂的话,尽量结合自己的理解用自己的语言来表达清楚,这样,如果以后需要复习的话,直接看简记就可以了,这样比看书效率高一点,毕竟全是知识点的描述。
ECMAScript 6 简介
ECMAScript
和 JavaScript
的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript
方言还有 JScript
和 ActionScript
)。日常场合,这两个词是可以互换的。
2015 年 6 月正式发布了ES6
。
之后的每年的 6 月份正式发布一次,作为当年的正式版本。
ES6
既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript
的下一代标准,涵盖了 ES2015
、ES2016
、ES2017
等等 。
let 和 const 命令
基本规则
let
声明的变量只在它所在的代码块有效。
for
循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域 。
for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc
不存在变量提升
let
命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错,let
不存在变量提升
暂时性死区
ES6
明确规定,如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。 语法上,称为“暂时性死区”(temporal dead zone
,简称 TDZ
) 。
“暂时性死区”也意味着typeof
不再是一个百分之百安全的操作。 只要处于暂时性死区的变量, typeof
运行时就会抛出一个ReferenceError
,不使用let
的时候未声明的变量还可以使用typeof
,如果使用了let
,在let
声明变量之前使用typeof
操作这个变量,就会抛异常的。
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
不允许重复声明
let
不允许在相同作用域内,重复声明同一个变量 。
块级作用域
let
实际上为 JavaScript
新增了块级作用域,解决了变量泄露的问题,这样就可以不用IIFE
写法了。
// IIFE 写法
(function () {
var tmp = ...;
...
}());
// 块级作用域写法
{
let tmp = ...;
...
}
块级作用域声明函数
ES6
引入了块级作用域,明确允许在块级作用域之中声明函数。 ES6
规定,块级作用域之中,函数声明语句的行为类似于let
,在块级作用域之外不可引用。
以下规则只对 ES6
的浏览器实现有效:
- 允许在块级作用域内声明函数。
- 函数声明类似于
var
,即会提升到全局作用域或函数作用域的头部。 - 同时,函数声明还会提升到所在的块级作用域的头部。
因为环境的差异,所以避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。
ES6
的块级作用域必须有大括号,如果没有大括号,JavaScript
引擎就认为不存在块级作用域 。
// 第一种写法,报错
if (true) let x = 1;
// 第二种写法,不报错
if (true) {
let x = 1;
}
严格模式下,函数只能声明在当前作用域的顶层。
这里的记录太简略,详情查看
const 命令
const
声明一个只读的常量。一旦声明,常量的值就不能改变 ,const
一旦声明变量,就必须立即初始化 。
const
的作用域与let
命令相同:只在声明所在的块级作用域内有效 。
const
命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
const
声明的常量,也与let
一样不可重复声明。
const
声明变量的本质是,变量的内存地址将不能改变,不是变量内部的值不能改变,这意味着可以改变声明为常量的数组和对象里面的值。
如果要彻底的冻结一个对象,使其完全不能改变,使用下面的方式:
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach( (key, i) => {
if ( typeof obj[key] === 'object' ) {
constantize( obj[key] );
}
});
};
ES6 声明变量的六种方法【考点?】
var
命令、function
命令、let
、const
命令、import
命令、class
命令
顶层对象的属性
在浏览器中的顶层对象为window
对象, 从 ES6
开始,全局变量将逐步与顶层对象的属性脱钩 , var
命令和function
命令声明的全局变量,依旧是顶层对象的属性 , let
命令、const
命令、class
命令声明的全局变量,不属于顶层对象的属性。
globalThis对象
因为各种环境下的顶层对象都不一样,所以为了统一顶层对象,引入了globalThis
对象
- 浏览器里面,顶层对象是
window
,但Node
和Web Worker
没有window
。 - 浏览器和
Web Worker
里面,self
也指向顶层对象,但是Node
没有self
。 Node
里面,顶层对象是global
,但其他环境都不支持。
任何环境下,globalThis
都是存在的,都可以从它拿到顶层对象,指向全局环境下的this
。