ES6: 快速体验,及实用小贴士
2016 年是 ES6 大力推广和普及的黄金时期,也是今年的流行趋势, 就一个 ES6 关键词, 在 GitHub 上就有这么多搜索结果。(赶紧跟上大部队!)
简介
ES6 是 ECMAScript 6 的简称,是 ECMA-262 的第 6 版本。
ES5、ES2015 / ES6、ES2016 / ES7、ES2017 / ES8 这些关键词具体代表什么?
ES5 发布于 2009 年。
ES6,比起 ES5,是第一个大版本更新,在 2015-06 发布,所以又称 ES2015。
ES7 和 ES8 统称为 ECMAScript Next。
ES7 在 2016-06 发布,又称 ES2016。
ES8 在 2017-06 发布,又称 ES2017。
ECMAScript 与 JavaScript 有什么关系?
前者是后者的语言标准,后者是前者的一个实现。
ES6 在浏览器,Node.js 支持如何,适不适合开发,生产?
浏览器: ECMAScript 兼容列表
Node.js:ES2015 Support
工具:使用一些转换工具,可以把 ES6 => ES5
为什么要学习新语法?
当前很多库、框架、工具都在使用 ES6+ 进行开发,典型的就是 React 和 Vue,使用新语法特性的优势进行快速开发,然后使用转换构建工具部署生产代码。
ES6 新特性
Arrows and Lexical This
「箭头」函数(
=>
)和this
:使用「箭头」函数我们可以体验函数式编程的”美”,高效、简洁,当然也要注意上下文
this
。e.g.
// old
// new
猜猜猜
- a.js
// c(2) = ?
- b.js
// circle.c(2) = ?
- c.js
// circle.c(2) = ?
Classes
类:
基于原型链的语法糖,简单、清晰;面向对象编程更加轻松。
再也不会被其他语言吐槽了!e.g.
// old Cat.prototype.speak = Lion.prototype = Cat.prototype
// new
猜猜猜
- cat.js
// Cat.prototype= ?
- getters-setters.js
// a.name ? // a.name = 'Tom' // a.name ?
// Bar.prototype ?
Enhanced Object Literals
改进对象声明:
大大减少了代码量,创建对象更加简洁。
属性缩写
函数缩写
属性名计算
e.g.
// old
// new
猜猜猜
- returns.js
// generate('github', 5) ?
- cumputed-properties.js
// create('/', 'get') ?
- complicated.js
Template Strings
模板字符串:
终于可以舒服的写多行字符串了,这功能等到花儿都谢了!
支持多行
支持变量绑定
也支持对字符串不转义,不解析
e.g.
// old
// new
猜猜猜
- raw-tag.js
// console.log(t0) // console.log(t1)
- expression.js
// console.log("Fifteen is " + (a + b) + " and\nnot " + (2 * a + b) + ".") // console.log(`Fifteen is ${a + b} and\nnot ${2 * a + b}.`)
- custom-tag.js
// generatePath`GET: ${user}${id}${profile}`
Destructuring
解析赋值
可以轻松获取对象、数组等的元素,并赋值到指定变量
- Array ArrayLike Object 等,具有迭代器接口的对象
e.g.
// old
// new
猜猜猜
- print.js
// print({ name: 'ES6', age: 2015 }) ?
- alias.js
// name, es, age?
- defaults.js
// version ? // fullname, f ? // y, m, d, h ?
Default + Rest + Spread
默认值、余下参数(Rest),数组展开(Spread)
默认值: 减少了对输入参数的检查的代码量,即可读又简洁
Rest:对参数数组操作更加灵活
Spread:可以看作是 Rest 的反操作,更加方便对数组的操作
e.g.
// old
// new
猜猜猜
- string.js
// [...str] ?
- concat.js
// c ?
- parse-args.js
/** * 解析参数,返回特定格式 * * @return {Array} [arr, options, cb] */ // parseArgs('users') ? // parseArgs('users', {}) ? // parseArgs('users', () => {}) ? // parseArgs('users', {}, () => {}) ? // parseArgs('users', 'books') ? // parseArgs(['users', 'books']) ?
Let + Const
变量、常量定义声明:
当满世界都是
var
的时候,变量管理是个神坑!块级作用域
const: 一次性声明
e.g.
// old // 函数作用域下覆盖全局作用域 // 变量泄漏 for ; i < s.length; i++ i // 5
// new for ; i < s.length; i++
猜猜猜
- global.js
// this.a ? // this.b ? // this.c ?
- for.js
for ; i < s.length; i++ i // ?
Iterators + For..Of
迭代器和
for..of
像
[...arr]
就是迭代器一个很好的例子。可迭代协议:ES6 定义了一套统一的标准,允许对 JavaScript 对象自定义它们的迭代行为。
内置可迭代类型有 String,Array,TypedArray,Map,Set,因为在它们的原型对象上已经有了
[Symbol.iterator]
方法。
e.g.
// old for in arr
// new for of arr
猜猜猜
- for-loops.js
Array.prototype.arrCustom = arr.isArray = true for in arr for of arr
- iterable.js
for of iterable // [...iterable] ?
- iterator.js
// ? // ? // ? // ... // ? // ? // ? // ...
Generators
生成器:
生成器大杀器!
e.g.
// old
// new
猜猜猜
- generatable.js
for of // [...generatable()] ?
- next.js
// ? // ? // ? true // ? // ? // ? // ? // ? // ?
- return.js
true // ? // ? 1 // ? // ?
- yield.js
; // ?
Unicode
Unicode
- 加强对 Unicode 的支持,并且扩展了字符串对象
e.g.
// same as ES5.1 '𠮷'.length == 2 // new RegExp behaviour, opt-in ‘u’ '𠮷'/./u.length == 2 // new form ;'\u{20BB7}' == '𠮷' == '\uD842\uDFB7' // new String ops '𠮷'0 == 0x20bb7 // for-of iterates code points for of '𠮷'
Modules ?
模块话系统目前还未实现!
Subclassable Built-ins
子类可继承自内置数据类型
真的太方便了,比如想对 Array 进行扩展,现在无需修改
Array.prototype
,extends Array
就可以了。- Array Boolean String Number Map Set Error RegExp Function Promise
e.g.
// old // This is danger. Array.prototype.sum =
// new
猜猜猜
ctx ctx.arr // ?
Map + Set + WeakMap + WeakSet
新增
Map
Set
WeakMap
WeakSet
几种高效的数据类型e.g.
// Sets 'hello' 'goodbye' 'hello' s.size === 2 'hello' === true // Maps 'hello', 42 s, 34 s == 34 // Weak Maps s, wm.size === undefined // Weak Sets // Because the added object has no other references, it will not be held in the set
Proxies
当我们不想把对象暴露出来,不想直接操作它们,想增加一层校验时,
Proxies
是一个最佳方案。
但当增加了Proxies
这一层,对性能还是会有影响的。e.g.
// old // outer.name
// new p.name p.name = 2 p.name = 'ES2015'
猜猜猜
bar foo p p.n // ? 1 p.n // ? 2 p.n // ? 1 p.n // ? p.n = 233 p.n // ?
-
符号:
唯一性
不可变
不列入对象的
Object.getOwnPropertyNames(obj)
和Object.keys(obj)
想给对象打一个暗号,再也不难了!
e.g.
// old obj.id // 1 obj.id = 2 obj.id // 2
// new obj // undefined obj = 2 obj // undefined for of obj
Math + Number + String + Array + Object APIs
新增 APIs,数据操作更加方便。
e.g.
Number.EPSILON Infinity // false 'NaN' // false 3 // 1.762747174039086 3, 4 // 5 2, 32 - 1, 2, 32 - 2 // 2 'abcde''cd' // true 'abc'3 // "abcabcabc" '*' // Returns a real Array 1, 2, 3 // Similar to new Array(...), but without special one-arg behavior 7, 1 // [0,7,7] x == 2 // 1 // iterator [0, "a"], [1,"b"], [2,"c"] // iterator 0, 1, 2 // iterator "a", "b", "c" Point,
Binary and Octal Literals
二进制
b
,八进制o
字面量e.g.
0b111110111 === 503 // true 0o767 === 503 // true 0x1f7 === 503 // true
Promises
Promises:更加优雅的异步编程方式。想更加清晰了解
Promise
的执行过程,可以看这个可视化工具 promisees。面对异步编程,
callback-hell
就是 JavaScript 给人的最大诟病!e.g.
// old 233,
// new 233 233 233 233 err // ...
猜猜猜
- simple-promise.js
'https://nodejs.org/static/images/logo-header.png' img err
- all.js
- race.js
- reduce.js
, cb
-
反射 API:公开了对象的元操作,效果跟 Proxy API 相反
e.g.
O, 'b', O = 3 O // ['a', 'b', Symbol(c)] instance.c // 42
Tail Calls
优化了尾递归算法,保证栈不会无限增长,使得尾递归算法安全。
快速体验
对以上新特性,快速体验一番,环境包括 浏览器 和 Node.js
高级应用
深入学习特性,应用生产
兼容,代码转换
使用转换工具,对 ES6+ 的代码进行转换,适配浏览器或者 Node < v6
其他
http://es6.ruanyifeng.com
https://github.com/lukehoban/es6features
https://babeljs.io/docs/learn-es2015/
https://ponyfoo.com/articles/tagged/es6-in-depth
https://github.com/bevacqua/es6
https://github.com/DrkSephy/es6-cheatsheet
https://github.com/ericdouglas/ES6-Learning
https://github.com/addyosmani/es6-tools
https://github.com/bevacqua/promisees
License
授权:署名-非商业性使用