ES6 -> ECMA 标准
ES6 的第一个版本,就这样在 2015 年 6 月发布了,正式名称就是《ECMAScript 2015 标准》(简称 ES2015)。
2016 年 6 月,小幅修订的《ECMAScript 2016 标准》(简称 ES2016)如期发布,这个版本可以看作是 ES6.1 版,
因为两者的差异非常小(只新增了数组实例的 includes 方法和指数运算符),基本上是同一个标准。根据计划,
2017 年 6 月发布 ES2017 标准。
因此,ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了
ES2015、ES2016、ES2017 等等,而 ES2015 则是正式名称,特指该年发布的正式版本的语言标准。
-------------------------------------------------------------------------------------------------
ES2015
ES6 -> 2015 年 6 月 ES6.0
每年 6 月份,发布一个版本
2016 年 6 月 ES6.1 ES7
ES2016
2017 年 6 月 ES6.2(async await)
ES8
ES2017
ESnext: '下一代 js'语言
-------------------------------------------------------------------------------------------------
一种新的语法从提案到变成正式标准,需要经历五个阶段。每个阶段的变动都需要由 TC39 委员会批准。
Stage 1
展示阶段
Stage 2
征求意见阶段
Stage 3
草案阶段
Stage 4
候选阶段
Stage 5
定案阶段(标准)
一个提案只要能进入 Stage 2,就差不多会出现在以后的正式标准里面。ECMAScript 当前的所有提案,可以
在 TC39 的官方网站 GitHub.com/tc39/ecma262 查看。
react, vue, angularJs, angular
chrome, 对新的语法支持,发展迅猛
----------------------------------------------------------------------------------------------
ES6 环境:
webpack3.x
Traceur
1 Let
命令
基本用法
:
用来声明变量。它的用法类似于
var
,但是所声明的变量,只在
let
命令所在的代码块内有效
。
关于定义(声明变量
)
之前
:var a=212;
作用域:全局 局部(函数作用域)
Var
有可能污染全局
Let
相当于
var
Const
常量,定义好了不能改变
Let
注意事项:
1没有预解析,不存在变量提升
必须在代码块内,
let
定义的变量,在之前使用都会报错
先定义,后使用
2
同一个作用域内不能用
let
重新定义变量,赋值没问题
3 for
循环()里面是父级作用域,里面是子级块级作用域
如运行如下的代码
:
实例
1
{ let a = 10; var b = 1;}
结果如下
:
a // ReferenceError: a is not defined.
b // 1
实例
2
:
for
循环的计数器
for (let i = 0; i < 10; i++) {
// ...
}
console.log(i);
// ReferenceError: i is not defined
原因
:let
声明的是块级作用域
实例
3
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6]();
// 10
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6]();
// 6
注
:
for (let i = 0; i < 3; i++) { //
此处
i
的作用域为父级
let i = 'abc'; //
此处
i
的作用域为子级
console.log(i);
}
ES6
明确规定,如果区块中存在
let
和
const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭
作用域。凡是在声明之前就使用这些变量,就会报错。在代码块内,
使用
let
命令声明变量之前,该变量都是不可
用的。
这在语法上,称为
“
暂时性死区
”
(
temporal dead zone
,简称
TDZ
)
var tmp = 123;
if (true) {
tmp = 'abc';
// ReferenceError
引用错误
let tmp;
}
不允许重复声明
let
不允许在相同作用域内,重复声明同一个变量
//
报错
function func() {
let a = 10;
let a = 1;
}
因此,不能在函数内部重新声明参数。
function func(arg) {
let arg; //
报错
}
function func(arg) {
{
let arg; //
不报错
}
}
为什么需要块级作用域?
ES5
只有
全局作用域
和
函数作用域
,
没有块级作用域
,这带来很多不合理的场景。
1
内层变量可能会覆盖外层变量。
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f();
//undefined
2
用来计数的循环变量泄露为全局变量。
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i);
// 5
块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(
IIFE
)不再必要了。
// IIFE
写法
(function () {
var tmp = ...;
...
}());
//
块级作用域写法
{
let tmp = ...;
...
}
允许在块级作用域内声明函数。
函数声明类似于
var
,即会提升到全局作用域或函数作用域的头部。
同时,函数声明还会提升到所在的块级作用域的头部。
//
浏览器的
ES6
环境
function f() { console.log('I am outside!'); }
(function () {
var f = undefined;
if (false) {
function f() { console.log('I am inside!'); }
}
f();
}());
// Uncaught TypeError: f is not a function
应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句
//
函数声明语句
{
let a = 'secret';
function f() {
return a;
}
}
//
函数表达式
{
let a = 'secret';
let f = function () {
return a;
};
}
ES6
的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错
通俗的讲
:
块级作用域的标致就是大括号
//
不报错
'use strict';
if (true) {
function f() {}
}
//
报错
'use strict';
if (true)
function f() {}
2 const
1.
const
声明一个只读的常量。一旦声明,
常量的值就不能改变
。声明的变量不得改变值,这意味着,
const
一旦声明变量,就必须立即赋值,不能留到以后赋值
。
const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.
2.
const
的作用域与
let
命令相同:只在声明所在的块级作用域内有效。
if (true) {
const MAX = 5;
}
MAX
// Uncaught ReferenceError: MAX is not define
3.
const
命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用
if (true) {
console.log(MAX);
// ReferenceError
const MAX = 5;
}
4.
ES6
声明变量的
6
种方法
Var function let const import class
Const
的特性与
let
一样
Const
定义的变量是不能修改的
Const
定义为变量,必须有值,不能后赋值
ES6
中如果要冻结对象常量
object.freeze
如配置文件
Const config={
Host:
Username:
Password;
Version:
}
IIFE
(function(){
//TODO
})