最好的學(xué)習(xí)ES6的方法,是為每一個(gè)ES6示例提供一個(gè)等價(jià)的ES5實(shí)現(xiàn)。外面已經(jīng)有不少介紹ES6的文章,本文將只講其中一些。
// ES6
import React from 'react';
import {Route, DefaultRoute, NotFoundRoute} from 'react-router';
// ES5
var React = require('react');
var Router = require('react-router');
var Route = Router.Route;
var DefaultRoute = Router.DefaultRoute;
var NotFoundRoute = Router.NotFoundRoute;
使用ES6中的解構(gòu)賦值(destructuring assignment),我們能導(dǎo)入模塊的子集,這對(duì)于像react-router和underscore這樣不止輸出一個(gè)函數(shù)的模塊尤其有用。
需要注意的是ES6 import的優(yōu)先級(jí)很高,所有的依賴模塊都會(huì)在模塊代碼執(zhí)行之前加載,也就是說(shuō),你無(wú)法像在CommonJS一樣有條件的加載模塊。之前我嘗試在一個(gè)if-else條件里import模塊,結(jié)果失敗了。
想了解import
的更多細(xì)節(jié),可訪問(wèn)它的MDN頁(yè)面。
// ES6
function Add(x) {
return x + x;
}
export default Add;
// ES5
function Add(x) {
return x + x;
}
module.exports = Add;
想學(xué)習(xí)ES6模塊的更多細(xì)節(jié),這里有兩篇文章ECMAScript 6 modules和Understanding ES6 Modules。
ES6 class只不過(guò)是現(xiàn)有的基于原型繼承機(jī)制的一層語(yǔ)法糖,了解這個(gè)事實(shí)之后,class
關(guān)鍵字對(duì)你來(lái)說(shuō)就不再像一個(gè)其它語(yǔ)言的概念了。
// ES6
class Box {
constructor(length, width) {
this.length = length;
this.width = width;
}
calculateArea() {
return this.length * this.width;
}
}
let box = new Box(2, 2);
box.calculateArea(); // 4
// ES5
function Box(length, width) {
this.length = length;
this.width = width;
}
Box.prototype.calculateArea = function() {
return this.length * this.width;
}
var box = new Box(2, 2);
box.calculateArea(); // 4
另外,ES6中還可以用extends
關(guān)鍵字來(lái)創(chuàng)建子類(lèi)。
class MyComponent extends React.Component {
// Now MyComponent class contains all React component methods
// such as componentDidMount(), render() and etc.
}
了解ES6 class更多信息可查看Classes in ECMAScript 6這篇博文。
var
與let
這兩個(gè)關(guān)鍵字唯一的區(qū)別是,var
的作用域在最近的函數(shù)塊中,而let
的作用域在最近的塊語(yǔ)句中——它可以是一個(gè)函數(shù)、一個(gè)for循環(huán),或者一個(gè)if語(yǔ)句塊。
這里有個(gè)很好的示例,來(lái)自MDN:
var a = 5;
var b = 10;
if (a === 5) {
let a = 4; // The scope is inside the if-block
var b = 1; // The scope is inside the function
console.log(a); // 4
console.log(b); // 1
}
console.log(a); // 5
console.log(b); // 1
一般來(lái)說(shuō),let
是塊作用域,var
是函數(shù)作用域。
一個(gè)箭頭函數(shù)表達(dá)式與函數(shù)表達(dá)式相比有更簡(jiǎn)短的語(yǔ)法,以及從語(yǔ)法上綁定了this
值。
// ES6
[1, 2, 3].map(n => n * 2); // [2, 4, 6]
// ES5
[1, 2, 3].map(function(n) { return n * 2; }); // [2, 4, 6]
注意:如果參數(shù)只有一個(gè),圓括號(hào)是可選的,到底是否強(qiáng)制使用取決于你,不過(guò)有些人認(rèn)為去掉括號(hào)是壞的實(shí)踐,有些人則無(wú)所謂。
除了更短的語(yǔ)法,箭頭函數(shù)還有什么用途呢?
考慮下面這個(gè)示例,它來(lái)自于我將這個(gè)項(xiàng)目轉(zhuǎn)換為使用ES6之前的代碼:
$.ajax({ type: 'POST', url: '/api/characters', data: { name: name, gender: gender } })
.done(function(data) {
this.setState({ helpBlock: data.message });
}.bind(this))
.fail(function(jqXhr) {
this.setState({ helpBlock: jqXhr.responseJSON.message });
}.bind(this))
.always(function() {
this.setState({ name: '', gender: '' });
}.bind(this));
上面的每個(gè)函數(shù)都創(chuàng)建了自己的this
作用域,不綁定外層this
的話我們是無(wú)法在示例中調(diào)用this.setState
的,因?yàn)楹瘮?shù)作用域的this
一般是undefined。
當(dāng)然,它有繞過(guò)的方法,比如將this
賦值給一個(gè)變量,比如var self = this
,然后在閉包里用self.setState
代替this.setState
即可。
而使用等價(jià)的ES6代碼的話,我們沒(méi)有必要如此麻煩:
$.ajax({ type: 'POST', url: '/api/characters', data: { name: name, gender: gender } })
.done((data) => {
this.setState({ helpBlock: data.message });
})
.fail((jqXhr) => {
this.setState({ helpBlock: jqXhr.responseJSON.message });
})
.always(() => {
this.setState({ name: '', gender: '' });
});
ES6的講解就到此為止了,下面讓我們看看React,到底是什么讓它如此特殊。
更多建議: