Introduction
ECMAScript 6 于今年6月正式成为了标准,关于ES6,我们最大的疑虑可能是客户端浏览器还没有完全支持它,也就node.js用用。
有很多种手段可以解决这个问题,比如:通过webpack(请参考博主webpack系列的文章)与babel-loader.
如下图,浏览器借助它们就能跑ES6语法了,也没有增加js负荷(1.6KB)。以下的ES6特性,都可以放心的使用。
BABEL官网链接
Arrows and Lexical This
Arrows are a function shorthand using the => syntax. They are syntactically similar to the related feature in C#, Java 8 and CoffeeScript. They support both expression and statement bodies. Unlike functions, arrows share the same lexical this as their surrounding code. =>语法已经加入到js啦,用过java c# 或者CoffeeScript的同学可能对它很熟悉。与函数不同的是,=>里面的语句是与父级共享作用域的(不像function自己再开个)。 ``` // Expression bodies var odds = evens.map(v => v + 1); var nums = evens.map((v, i) => v + i);// Statement bodies
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v);
});
// Lexical this
var bob = {
_name: "Bob",
_friends: [],
printFriends() {
this._friends.forEach(f =>
console.log(this._name + " knows " + f));
}
};
<h2 id="classes">Classes</h2>
ES2015 classes are a simple sugar over the prototype-based OO pattern. Having a single convenient declarative form makes class patterns easier to use, and encourages interoperability. Classes support prototype-based inheritance, super calls, instance and static methods and constructors.
Classes支持属性的继承,调用父级的函数,静态方法,构造器。
class SkinnedMesh extends THREE.Mesh {
constructor(geometry, materials) {
super(geometry, materials);
this.idMatrix = SkinnedMesh.defaultMatrix();
this.bones = [];
this.boneMatrices = [];
//...
}
update(camera) {
//...
super.update();
}
static defaultMatrix() {
return new THREE.Matrix4();
}
}
<h2 id="enhanced-object-literals">Enhanced Object Literals</h2>
Object literals are extended to support setting the prototype at construction, shorthand for foo: foo assignments, defining methods and making super calls. Together, these also bring object literals and class declarations closer together, and let object-based design benefit from some of the same conveniences.
对象在语法方面的扩展:现在可以在构造阶段就配prototype,以前的foo:foo现在可以简写为foo。
var obj = {
// proto
proto: theProtoObj,
// Does not set internal prototype
'proto': somethingElse,
// Shorthand for ‘handler: handler’
handler,
// Methods
toString() {
// Super calls
return "d " + super.toString();
},
// Computed (dynamic) property names
[ "prop_" + (() => 42)() ]: 42
};
> 部分浏览器不支持 `__proto__`,[参考这里](http://kangax.github.io/compat-table/es6/#__proto___in_object_literals)
<h2 id="template-strings">Template Strings</h2>
Template strings provide syntactic sugar for constructing strings. This is similar to string interpolation features in Perl, Python and more. Optionally, a tag can be added to allow the string construction to be customized, avoiding injection attacks or constructing higher level data structures from string contents.
ES6引入了Perl,Python中的模版字符串语法,支持了多行字符串。
// Basic literal string creation
This is a pretty little template string.
// Multiline strings
In ES5 this is not legal.
// Interpolate variable bindings
var name = "Bob", time = "today";
Hello ${name}, how are you ${time}?
<h2 id="destructuring">Destructuring</h2>
Destructuring allows binding using pattern matching, with support for matching arrays and objects. Destructuring is fail-soft, similar to standard object lookup foo["bar"], producing undefined values when not found.
Destructuring 使得我们可以引入更多的匹配式的代码
// 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;
这里插一句,BABEL会把以上代码转换成如下
"use strict";
var _ref = [1, 2, 3];
var a = _ref[0];
var b = _ref[2];
var _getASTNode = getASTNode();
var a = _getASTNode.op;
var b = _getASTNode.lhs.op;
var c = _getASTNode.rhs;
var _getASTNode2 = getASTNode();
var op = _getASTNode2.op;
var lhs = _getASTNode2.lhs;
var rhs = _getASTNode2.rhs;
function g(_ref2) {
var x = _ref2.name;
console.log(x);
}
g({ name: 5 });
var _ref3 = [];
var a = _ref3[0];
a === undefined;
var _ref4 = [];
var _ref4$0 = _ref4[0];
var a = _ref4$0 === undefined ? 1 : _ref4$0;
a === 1;
<h2 id="default-rest-spread">Default + Rest + Spread</h2>
Callee-evaluated default parameter values. Turn an array into consecutive arguments in a function call. Bind trailing parameters to an array. Rest replaces the need for arguments and addresses common cases more directly.
默认参数已经得到支持,借助...我们可以将数组延展成参数,可以用来替代arguments,也可以用来传参。
function f(x, y=12) {
// y is 12 if not passed (or passed as undefined)
return x + y;
}
f(3) == 15
function f(x, ...y) {
// y is an Array
return x * y.length;
}
f(3, "hello", true) == 6
function f(x, y, z) {
return x + y + z;
}
// Pass each elem of array as argument
f(...[1,2,3]) == 6
<h2 id="let-const">Let + Const</h2>
块级作用域,博主 [这篇文章](http://www.cnblogs.com/E-WALKER/p/4782475.html)说的更详细点。
<h2 id="iterators-for-of">Iterators + For..Of</h2>
terator objects enable custom iteration like CLR IEnumerable or Java Iterable. Generalize for..in to custom iterator-based iteration with for..of. Don’t require realizing an array, enabling lazy design patterns like LINQ.
C#中的IEnumerable或者说JAVA中的Iterable在ES6中亦有实现,注意,使用for..of而非for..in
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);
}
> 需要引入[polyfill](http://babeljs.io/docs/usage/polyfill/)
<h2 id="map-set-weak-map-weak-set">Map + Set + WeakMap + WeakSet</h2>
Efficient data structures for common algorithms. WeakMaps provides leak-free object-key’d side tables.
新的WeakXXX解决了内存泄漏问题.
// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;
// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined
// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });
// Because the added object has no other references, it will not be held in the set
> 需要引入[polyfill](http://babeljs.io/docs/usage/polyfill/)
<h2 id="binary-and-octal-literals">Binary and Octal Literals</h2>
Two new numeric literal forms are added for binary (b) and octal (o).
现在可以使用二进制与八进制了。
0b111110111 === 503 // true
0o767 === 503 // true
> 目前babel还不支持Number("0o767").
<h2 id="promises">Promises</h2>
Promises are a library for asynchronous programming. Promises are a first class representation of a value that may be made available in the future. Promises are used in many existing JavaScript libraries.
关于Promises的资料有很多,现在js已经原生支持了。
> 需要引入[polyfill](http://babeljs.io/docs/usage/polyfill/)
<h2 id="reflect-api">Reflect API</h2>
Full reflection API exposing the runtime-level meta-operations on objects. This is effectively the inverse of the Proxy API, and allows making calls corresponding to the same meta-operations as the proxy traps. Especially useful for implementing proxies.
没错。。。支持反射了。
var O = {a: 1};
Object.defineProperty(O, 'b', {value: 2});
O[Symbol('c')] = 3;
Reflect.ownKeys(O); // ['a', 'b', Symbol(c)]
function C(a, b){
this.c = a + b;
}
var instance = Reflect.construct(C, [20, 22]);
instance.c; // 42
> 需要引入[polyfill](http://babeljs.io/docs/usage/polyfill/)
<h2 id="tail-calls">Tail Calls</h2>
Calls in tail-position are guaranteed to not grow the stack unboundedly. Makes recursive algorithms safe in the face of unbounded inputs.
调用堆栈的深度无限制了。
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 ES2015
factorial(100000)