关于es6的详细说明,能够参照个人系列文章es6 从入门到熟练,或者阮一峰的ECMAScript 6 入门。javascript
个人系列文章,是在阮一峰的基础上,增长了更多适合初中级开发者的内容(包括大量的示例代码和解释),以下降学习难度,丰富说明。html
本文是对es6总体的回顾,结合个人实际开发经验,对es6的一个小结。前端
为了精炼内容,es6里不经常使用的内容已经去掉,而对经常使用、重要的es6知识,附上简单的代码说明,并另附有详细说明的博文连接,方便初中级开发者理解。vue
关键字:IE九、Babel、Babel的垫片、脚手架java
首先,使用es6的前提是最低IE9,若是你须要兼容IE8,建议放弃es6,专心使用神器jQuery。node
其次,若是须要使用es6来编写,那么你须要Babel
转码器用于将你的es6代码转换为es5代码,用于兼容只能使用es5的环境。不然对于只能运行es5的环境(例如IE9),是没法运行es6代码的。git
第三,因为Babel在默认状况下,并非所有转换的,如如下说明:es6
Babel 默认只转换新的 JavaScript 句法(syntax),而不转换新的 API,好比Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(好比Object.assign)都不会转码。github
所以,咱们须要垫片,通常状况下能够用babel-polyfill,也能够用babel-runtime
,这两个有所差别。web
babel-polyfill会污染全局对象,即会对例如Object这样的对象添加方法,而babel-runtime只会转换es6语法的代码,但若是你须要调用Object.assign这样的方法,那就不行了。
因为细节不少,所以这里给几个参考连接吧:
看完以上两个,可能会以为应该同时使用这两个,然而并不须要,看下面这个连接:
transform-runtime 会自动应用 polyfill,即使没有使用 babel-polyfill的conanliu
于17 Dec 2016
提交的issues。
若是你使用的Vue.js,那么能够直接fork个人脚手架,而后当作本身的脚手架使用。
附脚手架连接:vue-scaffold,若是能够,给个star喔~~
若是你用的不是Vue.js,那么能够去搜一下你所使用的框架的脚手架,而后拿来使用。若是找不到,能够找使用带脚手架的该框架项目,而后down下来,删除对方的项目只取壳来用便可。(若是有许可,记得阅读一下许可看能不能这么干)
既然有let和const了,那么推荐优先使用这两个。
通常状况下,let能够直接替代var,对于常量,能够用const。
这不是必须的,但用这2个能够帮你规范写代码的习惯,因此仍是强烈推荐的。
比较蛋疼的是,用webtorm,let有时候不会高亮,只有var和const是高亮的。这个多是用的风格的问题,我也不太肯定。解决方案我本身是没找到,凑合用吧。
另外,let和var之间的一个重要区别是变量提高,因此若是你写代码不太规范的话,可能会报错,好好检查一下吧。
另外,阮一峰推荐将函数设置为常量,就像这样子:
const add = function (a, b) { return a + b }
我以为挺有道理的,推荐。
既然用es6,固然要用反引号这个高大上的东西了。
详细用法推荐我本身的博客:ECMAScript 6(7)模板字符串
最基本的用法,能够直接用反引号替代普通的引号(单引号和双引号)
例如:
let a = 'ab' // 能够直接用如下替换 let a = `ab`
并且通常状况下,简单需求不用再拼接字符串了~(另外,反引号也能够像普通字符串那样拼接)
如:
let str = '20004604'; let html = 'my QQ is ' + str; //用如下替换 let str = '20004604'; let html = `my QQ is ${str}`;
简单暴力省事。
最大的好处是简化了写法,如代码:
let obj = { a: 1, b: 2 } //old let a = obj.a; let b = obj.b; // es6 let {a, b} = obj
除了对象以外,还有数组也能够解构赋值,别忘了。
es6的对象,比早期版本的写起来舒服不少。
例如:
Object.assign()
来合并对象,实现继承或添加属性效果;列一些常见写法:
let obj = { // 对象属性是函数的时候能够简写 a(){ console.log('对象属性是函数的时候能够简写') }, // setter和getter的简写; get b() { return this._b }, set b(val) { this._b = val } } let c = '添加了一个c' // 经过``Object.assign()``来合并对象,实现继承或添加属性效果 // 能够用变量名只要做为对象的属性名,而且变量的值能够自动成为对象该属性名的值 Object.assign(obj, { c }) // 能够用属性名表达式 let d = "abcd" obj[d.replace(/abc/, '')] = '属性名表达式'
最经常使用的就两个:
...
;Array.from()
如代码:
function getArgs() { let foo = [...arguments] console.log(foo) let bar = Array.from(arguments) console.log(bar) } getArgs(1, 2, 3) // [1, 2, 3] // [1, 2, 3]
须要注意的一个特性:
Array(5)
这样生成带空位的数组时,处理他的时候会跳过空位数组的空位;函数经常使用特性有如下几个:
function test(..args){}
这样的,这个返回的是一个数组,而不是类数组。function test(a, b = 3) { console.log(a, b) console.log(this) } test.bind('Is this')(1) // 1 3 // Is this function test2(...args) { console.log(args.length) } test2(1, 2, 3, 4, 5) // 5
Set结构最大的特色是去重,Map结构最大的特色是kv结构。
Set:
Set和数组相似,能够存储元素,可是Set不能存储相同的值。
非引用类型变量来讲,就是值相等;对于引用类型变量来讲,指地址相等(而不是值相等)。详细状况请点击Set类型和WeakSet查看。
至于去重,通常是对数组使用。先做为参数生成一个Set类型变量,再利用扩展运算符变回数组,去重完成,完美。
利用扩展运算符,调用Set的迭代器接口
// 去重 let foo = new Set([1, 2, 3, 3, 3]) console.log([...foo]); // [1, 2, 3]
Map:
Map结构和对象很是相似,不过最大的区别在于,Map结构能够用其余类型做为key,例如数组、对象等。
Map能够参照这篇博客Map和WeakMap
示例代码:
let zhang = { firstName: "王" } let property = { gender: "男" } let foo = new Map() foo.set(zhang, property) foo.has(zhang) // true foo.get(zhang) // {gender: "男"}
Promise是es6的精华之一,他很是适用于异步处理。
Promise对象在使用的时候,分为两部分,第一部分是new Promise
这一步,第二部分是对返回的Promise实例进行处理的内容。
由于是经过执行resolve
或reject
来改变Promise的状态,从而决定执行then的时机的(相似回调函数),以及执行的哪个。所以写起来和回调函数相近,可是能够连写,避免回调地狱的状况。
关于Promise的详细介绍请阅读Promise(1)基础知识及以后三篇博客
如示例代码(对比普通ajax和promise)(另注:为了方便理解,仿jQuery的写法,而且没有用jQuery的$.ajax().then()
这种写法)
// 模拟ajax function ajax (options) { setTimeout(function () { options.success(options.url) }, 1000) } // old let foo = function (callback) { ajax({ url: "/1", success: function (result) { callback(result) } }) } let foo2 = function (result) { console.log(result) return function (callback) { ajax({ url: "/2", success: function (val) { callback(val) } }) } } // 核心,调用的时候若是是连续请求的话,基本要写成回调地狱了 foo(function (result) { foo2(result)(function (val) { console.log(val) }) }) // Promise let bar = function () { return new Promise((resolve, reject) => { ajax({ url: "/1", success: function (result) { resolve(result) } }) }) } let bar2 = function (result) { console.log(result) return new Promise((resolve, reject) => { ajax({ url: "/2", success: function (val) { resolve(val) } }) }) } // 核心,then连写便可 bar().then(function (result) { return bar2(result) }).then(function (result) { console.log(result) })
显然,then连写比回调函数的写法要方便一些。
若是面对的是特殊需求,好比是多个ajax请求所有完成后,再执行执行函数,那么Promise的优点会更大一些,而非Promise写法要麻烦不少。
甚至若是要对错误进行处理,那么Promise写法会更方便。
不过这里只是小结,就不细说了。
class是好东西。
有了class后,写构造函数、写类的继承的难度,降低了不少不少。
先附个人博文class(1)基本概念,以及以后5篇博文。
因为很简单,给一个示例大约就能理解这个是怎么用的:
class Foo { constructor () { console.log('this is constructor') this.defaultValue = '变量要在构造函数里赋值,而不能直接声明' } log () { console.log('log') } } let foo = new Foo() // this is constructor foo.log() // log foo.defaultValue // "变量要在构造函数里赋值,而不能直接声明"
es6的模块不一样于以往的CommonJS(node用,服务器环境),AMD(RequireJS的规范,浏览器环境,依赖前置)、CMD(SeaJS定义的规范,浏览器环境,依赖就近)。
他的特色有两个:
缺点是:
详细说明阅读这篇博客:es6的import和export,另外三个规范阅读这篇博客AMD、CMD、CommonJS
基本使用方式如示例代码:
// foo.js let foo = 'foo' export default foo // bar.js import foo from 'foo' console.log(foo)
这个并非es6的,而是es2017(又称es8)的内容。
能够认为async函数是Generator函数的语法糖,详细说明参照这篇博客:async函数。
他的前置知识比较多,包括Iterator遍历器、Generator状态机、Thunk函数(自动执行Generator 函数)。
简单的说,假若有多个异步请求,你须要让这些起步请求依次执行,例如在执行完前一个以后,再执行后一个。那么你就须要async函数了。
async函数可让你写这种请求如同写同步函数同样简单(对比【10】中的Promise更简单)。
如下示例是基于【10】中的代码,在最后一步执行的时候,改用async函数来完成
// 模拟ajax function ajax (options) { setTimeout(function () { options.success(options.url) }, 1000) } // Promise let bar = function () { return new Promise((resolve, reject) => { ajax({ url: "/1", success: function (result) { resolve(result) } }) }) } let bar2 = function (result) { console.log(result) return new Promise((resolve, reject) => { ajax({ url: "/2", success: function (val) { resolve(val) } }) }) } async function foo () { let result1 = await bar() let result2 = await bar2(result1) return result2 } foo().then(result => { console.log(result) })
能够发现,async让连续异步调用像写同步函数同样简单。
规范化开发,建议仍是用ESLint来帮忙检查吧。不会这个怎么行?
ESLint是一个语法规则和代码风格的检查工具,能够用来保证写出语法正确、风格统一的代码。
这里直接给一个阮一峰写的文章,等之后我再单独补一篇详细用法的博客。
es6经常使用内容基本就以上13点。
虽然es6实际包括了不少知识,例如:
但实际经常使用的就以上这些,若是只是平常使用的话,熟悉以上内容足够了。
但若要作的更好,那么应该深刻学习,es6新增的不少内容,是将传统后端语言的一些很好的思想,搬到JavaScript来,让js规范化。
对于专精于前端的同窗,学习es6的过程当中,能够学习到这些来自于其余语言的精华,所以建议至少完整的看一遍,勿要只知足于经常使用的这些API。