ES6
箭头函数
写法和JAVA8中一样,箭头指向函数体。和函数定义不一样的是,箭头函数和上下文共享this,就不用额外指定this了。
类
面向对象的福音!ES6中正式推出了类并且可以被继承(就不用通过原来的原型链的继承了)
增强了对象属性表达
原本赋值要写o = {foo:foo},现在只需要写o={foo}。方便了很多
另外还有一些,例如定义方法,调用super的方法,计算属性名等。
var obj = {
// __proto__
__proto__: theProtoObj,
// Shorthand for ‘handler: handler’
handler,
// Methods
toString() {
// Super calls
return "d " + super.toString();
},
// Computed (dynamic) property names
[ 'prop_' + (() => 42)() ]: 42
};
模板字符串
使用模板字符串``代替’‘的好处有:
- 可以在字符串中引用变量
- 可以直接在字符串中换行
解构
解构可以匹配数组和对象。主要是针对写法上更加简洁。
// list matching
var [a, , b] = [1,2,3];
// object matching
var { op: a, lhs: { op: b }, rhs: c }
= getASTNode()
// object matching shorthand
// binds `op`, `lhs` and `rhs` in scope
var {op, lhs, rhs} = getASTNode()
// Can be used in parameter position
function g({name: x}) {
console.log(x);
}
g({name: 5})
// Fail-soft destructuring
var [a] = [];
a === undefined;
// Fail-soft destructuring with defaults
var [a = 1] = [];
a === 1;
默认值和Spread Operator
在函数定义的时候可以写默认值,更加方便获取值和处理undefined的情况。可以代替原有的apply的写法,直接使用…args
Let和Const
这个是我很喜欢的定义,比var更加规范,明确了作用域。会让变量的存在更加明确。
遍历以及For..of
可以自己定义对象的迭代方法,并且利用for..of去遍历它。主要是利用对象中的一个属性Symbol.iterator
let fibonacci = {
[Symbol.iterator]() {
let pre = 0, cur = 1;
return {
next() {
[pre, cur] = [cur, pre + cur];
return { done: false, value: cur }
}
}
}
}
for (var n of fibonacci) {
// truncate the sequence at 1000
if (n > 1000)
break;
console.log(n);
}
Generators
可以利用function和yield去做迭代。function会生成一个Generator的事例,这个事例包含了next和throw方法。这些可以帮助回到一个generator。
Unicode
在正则表达式中添加了对Unicode的支持。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode
模块化
可以使用import和export做导入和输出了。隐性的异步模型,只有当所需要的模块加载和处理完成以后才会执行代码
Map,WeakMap, Set, WeakSet
新的数据结构。
代理Proxies
相当于对目标对象增加了一个代理人,所有对该对象的访问和修改都需要经过这个中间层,这个中间层会对你的操作经过一层处理。这样的话就不会让你直接接触和修改到目标对象。
以下是所有可以进行的meta-operations
var handler =
{
get:...,
set:...,
has:...,
deleteProperty:...,
apply:...,
construct:...,
getOwnPropertyDescriptor:...,
defineProperty:...,
getPrototypeOf:...,
setPrototypeOf:...,
enumerate:...,
ownKeys:...,
preventExtensions:...,
isExtensible:...
}
Symbols
Symbol是ES6中一个新的原始数据类型,使用Symbol()创建一个Symbol对象,并且可以传入一个description,就是这个symbol的描述。在ES6以后,对象可以用string或者symbol作为属性。可以通过getOwnPropertySymbols获取所有使用symbol的属性。另外Reflect.ownKeys可以获取到所有的keys包括string和symbol。
内置类的继承
在ES6中,Array,Date和Dom的Element是可以被继承的。
babel 部分支持,由于ES5引擎的限制Date,Array,Error不被支持,但是HTMLElement是被支持的
新增APIs
Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false
Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2
"abcde".includes("cd") // true
"abc".repeat(3) // "abcabcabc"
Array.from(document.querySelectorAll('*')) // Returns a real Array
Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior
[0, 0, 0].fill(7, 1) // [0,7,7]
[1, 2, 3].find(x => x == 3) // 3
[1, 2, 3].findIndex(x => x == 2) // 1
[1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2]
["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
["a", "b", "c"].keys() // iterator 0, 1, 2
["a", "b", "c"].values() // iterator "a", "b", "c"
Object.assign(Point, { origin: new Point(0,0) })
比较有趣的地方是findIndex比较于indexOf可以利用Object.is去帮助定位到NaN。
另外es7中新增的includes也可以检测到NaN
二进制和8进制的写法
0b111110111 === 503 // true
0o767 === 503 // true
Promise
Promise解决了回调地狱的问题,整个写法会更加优雅。
复习一下:
异步的实现有以下几种
- 回调函数
- 发布和订阅
- 事件监听
- Promise
- Generator
Reflect API
封装了一些Object上属于语言内部的属性在Reflect上,并且修改了一些属性方法。与Proxy上的方法一一对应,可以方便的使用代理。
Tail Calls
尾部调用(大概这个名字吧)。ES6针对尾部调用做了优化。所谓尾部调用就是函数的最后一步是调用函数。
例如return functionA()。但如果是return functionA() + functionB()就不是尾部调用。
ES6的优化保证不会堆栈溢出。
function factorial(n, acc = 1) {
'use strict';
if (n <= 1) return acc;
return factorial(n - 1, n * acc);
}
// Stack overflow in most implementations today,
// but safe on arbitrary inputs in ES6
factorial(100000)
ES7
Array.includes()
和indexOf很像,比之更加简洁,但是也有一些区别, includes是可以判断NaN的,但是indexOf不可以。
**指数运算
ES8
async/await
Object.values
Object.entries
String padding
函数参数列表结尾允许逗号
Object.getOwnPropertyDescriptors(obj)
References
Medium javascript-brief-history-and-ecmascript-es6-es7-es8-features