ECMAScript 6(简称ES6)是JavaScript语言的下一代标准。因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015。
虽然现在不是所有浏览器都能兼容ES6全部特性,但是越来越多的程序员在实际项目当中已经开始使用ES6。同时配合Babel等工具,ES6的普及也是越来越广泛。下面总结一下开发当中使用频率比较高的ES6新语法。
let, const
这两个的用途和var类似,都是用来声明变量,下面例子
1 | var name = 'zach' |
使用var两次输出都是obama,因为ES5只有全局作用域和函数作用域,没有块级作用域。而let实际上为JavaScript新增了块级作用域。用它所声明的变量,只在let命令所在的代码块内有效。
1 | let name = 'zach' |
另一个var带来的不合理场景就是用来计数循环变量泄露为全局变量
1 | var a = [] |
代码当中变量i是var声明的,在全局范围内都有效。所以每一次循环,新的i值都会覆盖旧值,导致输出的是最后一轮的i的值。而使用let则不会出现这个问题。
1 | var a = [] |
const也用来声明变量,但是声明的是常量。一旦声明,常量的值就不能改变
1 | const PI = Math.PI |
当我们尝试改变const声明的常量时,浏览器就会报错。
const有一个很好的应用场景,就是当我们引入第三方库时声明的变量,用const来声明可以避免未来不小心重命名而导致出现bug
1 | const monent = require('moment') |
class,extends,super
当初最早是先接触了python的面向对象的语法,后来接触到js的原型链,继承时觉得特别繁杂奇怪,直到再后来看到ES6中新添加的语法特性,顿时就觉得清晰了不少。
1 | class Animal { |
super关键字,它指代父类的实例(即父类的this对象)。子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
ES6的继承机制,实质就是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this。
arrow function
1 | function(i){ return i + 1; } //ES5 |
如果函数体内较复杂,则需用{}把代码包起来
1 | function(x, y) { |
除了语法简洁之外,箭头函数还有一个非常好的优点,当我们使用箭头函数时,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象,它的this是继承外面的,因此内部this就是外层代码块的this。
代码例子如下
1 | class Animal { |
运行上面的代码会报错,因为setTimeout 中的this是指向全局对象。传统解决方法有两种
第一种是将this传给self,再用self来指代this
1 | says(say){ |
第二种方法是用bind(this)
1 | says(say){ |
现在有了箭头函数,就不需要这么麻烦
1 | class Animal { |
template string
当要插入大段的html内容到文档当中去时,传统写法非常麻烦
1 | $("#result").append( |
如果用ES6的新特性模板字符串可以直接这么写
1 | $("#result").append(` |
destructuring
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,叫解构赋值
1 | let cat = 'ken' |
用ES6完全可以这么写
1 | let cat = "ken" |
反过来能这样赋值
1 | let dog = {type: 'animal', many: 2} |
default, rest
default 是指可以给函数参数添加默认值
传统方法是这样
1 | function animal(type){ |
如果用ES6可以直接这样写
1 | function animal(type="cat"){ |
rest语法也挺简单
1 | function animals(...types){ |
import export
传统组织js文件的方式缺乏模块化体系,无法将一个庞大js工程拆分成一个个功能相对独立但相互依赖的小工程,再用简单方法把它们连接起来。这可能导致两个问题。
- js代码变得臃肿难以维护
- 我们需要注意每个script标签在html的位置,因为它们通常有依赖关系
在ES6之前,我们需要利用第三方方案如CommonJS(服务器端)和AMD(浏览器端,如require.js)
传统的写法
首先是require.js的写法。假设有两个js文件: index.js 和 content.js 现在需要在 index.js 中使用 content.js 返回的结果
1 | // content.js |
然后require
1 | // index.js |
CommonJS
1 | //index.js |
ES6的写法
1 | //index.js |