最好的學習ES6的方法,是為每一個ES6示例提供一個等價的ES5實現。外面已經有不少介紹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中的解構賦值(destructuring assignment),我們能導入模塊的子集,這對于像react-router和underscore這樣不止輸出一個函數的模塊尤其有用。
需要注意的是ES6 import的優(yōu)先級很高,所有的依賴模塊都會在模塊代碼執(zhí)行之前加載,也就是說,你無法像在CommonJS一樣有條件的加載模塊。之前我嘗試在一個if-else條件里import模塊,結果失敗了。
想了解import
的更多細節(jié),可訪問它的MDN頁面。
// ES6
function Add(x) {
return x + x;
}
export default Add;
// ES5
function Add(x) {
return x + x;
}
module.exports = Add;
想學習ES6模塊的更多細節(jié),這里有兩篇文章ECMAScript 6 modules和Understanding ES6 Modules。
ES6 class只不過是現有的基于原型繼承機制的一層語法糖,了解這個事實之后,class
關鍵字對你來說就不再像一個其它語言的概念了。
// 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
關鍵字來創(chuàng)建子類。
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
這兩個關鍵字唯一的區(qū)別是,var
的作用域在最近的函數塊中,而let
的作用域在最近的塊語句中——它可以是一個函數、一個for循環(huán),或者一個if語句塊。
這里有個很好的示例,來自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
一般來說,let
是塊作用域,var
是函數作用域。
一個箭頭函數表達式與函數表達式相比有更簡短的語法,以及從語法上綁定了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]
注意:如果參數只有一個,圓括號是可選的,到底是否強制使用取決于你,不過有些人認為去掉括號是壞的實踐,有些人則無所謂。
除了更短的語法,箭頭函數還有什么用途呢?
考慮下面這個示例,它來自于我將這個項目轉換為使用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));
上面的每個函數都創(chuàng)建了自己的this
作用域,不綁定外層this
的話我們是無法在示例中調用this.setState
的,因為函數作用域的this
一般是undefined。
當然,它有繞過的方法,比如將this
賦值給一個變量,比如var self = this
,然后在閉包里用self.setState
代替this.setState
即可。
而使用等價的ES6代碼的話,我們沒有必要如此麻煩:
$.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,到底是什么讓它如此特殊。
更多建議: