Web前端之 ECMAScript6
1. ECMAScript6 简介
ECMAScript 和 JavaScript 的关系
ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现,常场合,这两个词是可以互换的。
名称详解
ECMAScript 6(以下简称 ES6)是 JavaScript 语言的标准,在 2015 年 6 月发布。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
版本 | 官方名称 | 发布日期 |
---|---|---|
ES1 | ECMAScript 1 | 1997 |
ES2 | ECMAScript 2 | 1998 |
ES3 | ECMAScript 3 | 1999 |
ES4 | ECMAScript 4 | 从未发布过 |
ES5 | ECMAScript 5 | 2009 |
ES5.1 | ECMAScript 5.1 | 2011 |
ES6 | ECMAScript 2015(ECMAScript 6) | 2015 |
ES7 | ECMAScript 2016 | 2016 |
ES8 | ECMAScript 2017 | 2017 |
… | … | … |
因此,ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017 等等
语法提案的批准流程
任何人都可以向标准委员会(又称 TC39 委员会)提案,要求修改语言标准。
一种新的语法从提案到变成正式标准,需要经历五个阶段。每个阶段的变动都需要由 TC39 委员会批准。
- Stage 0 - Strawman(展示阶段)
- Stage 1 - Proposal(征求意见阶段)
- Stage 2 - Draft(草案阶段)
- Stage 3 - Candidate(候选人阶段)
- Stage 4 - Finished(定案阶段)
一个提案只要能进入 Stage 2,就差不多肯定会包括在以后的正式标准里面。ECMAScript 当前的所有提案,可以在 TC39 的官方网站GitHub.com/tc39/ecma262查看。
ES6带来的新特性
let
和const
命令- 变量的解构赋值
- 字符串扩展
- 函数扩展
- 对象扩展
- 数组扩展
- 运算符扩展
- Promise对象
- Class
- Class 继承
- …
2. Nodejs简介
Nodejs诞生于2009年,主攻服务器方向,使得利用JavaScript也可以完成服务器代码的编写。
使用ES6,即JavaScript新特性,需要安装Nodejs环境。因为在有些浏览器上,对Es6的支持不是那么友好,因此,需要用Nodejs将ES6转换为ES5
Nodejs软件下载地址:https://nodejs.p2hp.com/download/ (国内)
建议直接安装在C盘,不要去更改默认路径,不然有可能后续使用的时候会出现问题。
检查是否安装成功命令:node -v
Nodejs官网
https://nodejs.org/en/
大量的库
在安装Nodejs
的同时,会附带一个npm
命令,npm
是Node的包管理工具,这样正是接下来我们要用到的
npm 的简单结构有助于 Node.js 生态系统的激增,现在 npm 仓库托管了超过 1,000,000 个可以自由使用的开源库包
npm
镜像
由于服务器在国外,所以下载速度比较慢,我们可以用国内的镜像
阿里镜像地址
https://npmmirror.com/
安装cnpm
在命令行运行如下命令即可
npm install -g cnpm --registry=https://registry.npmmirror.com
检测是否安装成功:cnpm -v
3. Babel转码器
Babel 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码,从而在老版本的浏览器执行。这意味着,你可以用 ES6 的方式编写程序,又不用担心现有环境是否支持
浏览器支持性查看
https://caniuse.com/
Babel官网
https://babeljs.io/
转码示例
原始代码用了箭头函数,Babel 将其转为普通函数,就能在不支持箭头函数的 JavaScript 环境执行了
// 转码前
input.map(item => item + 1);// 转码后
input.map(function (item) {return item + 1;
});
Babel安装流程
第一步:安装 Babel
npm install --save-dev @babel/core
第二步:配置文件.babelrc
Babel 的配置文件是.babelrc,存放在项目的根目录下。使用 Babel 的第一步,就是配置这个文件。
该文件用来设置转码规则和插件,基本格式如下
{"presets": [],"plugins": []
}
第三步:转码规则
presets字段设定转码规则,官方提供以下的规则集,你可以根据需要安装
npm install --save-dev @babel/preset-env
第四步:将规则加入.babelrc
{"presets": ["@babel/env"],"plugins": []
}
Babel命令行转码
Babel 提供命令行工具@babel/cli
,用于命令行转码
npm install --save-dev @babel/cli
基本用法如下
# 转码结果输出到标准输出
$ npx babel example.js# 转码结果写入一个文件
# --out-file 或 -o 参数指定输出文件
$ npx babel example.js --out-file compiled.js
# 或者
$ npx babel example.js -o compiled.js# 整个目录转码
# --out-dir 或 -d 参数指定输出目录
$ npx babel src --out-dir lib
# 或者
$ npx babel src -d lib
4. let 命令
ES6
新增了let
命令,用来声明变量。它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。
let块级作用域
{let num = 10;var sxt = 1;
}num // ReferenceError: itbaizhan is not defined.
sxt // 1
for
循环的计数器,就很合适使用let
命令
for (let i = 0; i < 10; i++) {// ...
}console.log(i);
// ReferenceError: i is not defined
对比var
和let
在循环中的应用
var a = [];
for (var i = 0; i < 10; i++) {a[i] = function () {console.log(i);};
}
a[6](); // 10
上面代码,输出的10
,而我们期待的是6
var a = [];
for (let i = 0; i < 10; i++) {a[i] = function () {console.log(i);};
}
a[6](); // 6
上面代码,输出的6
let不存在变量提升
var
命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined
。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用
为了纠正这种现象,let
命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;
let不允许重复声明
let
不允许在相同作用域内,重复声明同一个变量。
// 报错
function func() {let a = 10;var a = 1;
}// 报错
function func() {let a = 10;let a = 1;
}
5. Const 命令
const和let很像,唯一不同是一个是变量,一个是常量
const
声明一个只读的常量。一旦声明,常量的值就不能改变
const PI = 3.1415;
PI // 3.1415PI = 3;
// TypeError: Assignment to constant variable.
const
声明的变量不得改变值,这意味着,const
一旦声明变量,就必须立即初始化,不能留到以后赋值
const foo;
// SyntaxError: Missing initializer in const declaration
const
的作用域与let命令相同:只在声明所在的块级作用域内有效
if (true) {const MAX = 5;
}MAX // Uncaught ReferenceError: MAX is not defined
const
命令声明的常量也是不存在提升(即需要先声明后使用)
if (true) {console.log(MAX); // ReferenceErrorconst MAX = 5;
}
const
声明的常量,也与let
一样不可重复声明
var message = "Hello!";
let age = 25;// 以下两行都会报错
const message = "Goodbye!";
const age = 30;
6. 对象解构赋值
解构可以用于对象,可以简化调用,类似于别名
let {name,age} = {name:"iwen",age:20};
温馨提示
对象的属性没有次序,变量必须与属性同名,才能取到正确的值
let {age,name} = {name:"iwen",age:20};
age // 20
let {sex,age,name} = {name:"iwen",age:20};
sex // undefined
对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量
let { random,floor } = Math;
let { log } = console;
注意事项,如果要将一个已经声明的变量用于解构赋值,必须非常小心
let hello = "Hello";
let { hello } = {hello:"hello"}; // 报错let hello = "Hello";
({ hello } = {hello:"hello"}); // 正确
7. 字符串扩展
字符串Unicode 表示法
ES6 加强了对 Unicode 的支持,允许采用\uxxxx
形式表示一个字符,其中xxxx
表示字符的 Unicode 码点。
Unicode
统一码(Unicode),也叫万国码、单一码,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
"\u0061"
// "a"
字符串遍历器接口
for...of
循环遍历
for (let i of 'itbaizhan') {console.log(i);
}
模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
反引号避免了字符串拼接的繁琐
let url = "www.itbaizhan.com"
let h1 = "<a href='"+ url +"'>itbaizhan</a>"
let h2 =