ES6做爲新一代JavaScript標準,已正式與廣大前端開發者見面。爲了讓你們對ES6的諸多新特性有更深刻的瞭解,Mozilla Web開發者博客推出了《ES6 In Depth》系列文章。CSDN已獲受權,將持續對該系列進行翻譯,組織成【探祕ES6】系列專欄,供你們學習借鑑。本文爲該系列的第七篇。
javascript
本文接下來說述的是有關ES6箭頭函數(Arrow functions)的使用。前端
熱身java
箭頭符號在JS中一直扮演着重要的角色。在JS教程裏,一開始都會介紹如何使用箭頭括號來加註釋。例如:es6
<script language="javascript"> <!-- document.bgColor = "brown"; // red // --> </script>舊版瀏覽器接收的是兩個不支持的標籤和一句註釋,只有新版瀏覽器纔會識別這是JS代碼。
爲了處理這種奇怪的表達方式,瀏覽器的JS引擎會把<!—識別爲一行註釋的開始位置。這種處理機制一直沿用至今,如今於Node中也適用。除此以外,-->還能夠做爲遞增/減的操做符,例如while(n-->0) //n遞減至0。瀏覽器
咱們先回顧下箭頭符號的通常用法:函數
<!-- 單行註釋學習
--> 遞增/減的操做符this
<= 小於等於spa
=> ?.net
=>是ES6中新的用法,也就是本節要講述的內容。
隨處可見的函數式表達
在JS中頗有意思的地方是當咱們須要調用函數時,只需在運行代碼中的恰當位置添加就能夠了。例如要對按鈕的點擊作出響應,能夠這樣寫:
$("#confetti-btn").click(function (event) { playTrumpet(); fireConfettiCannon(); });在JS開始盛行前,這樣的代碼是使人奇怪的,由於不少語言當時都沒有相似的寫法。除了1958年List語言的lambda(匿名)函數有函數表達式功能,C++、Python、C#等語言長時間裏都是沒有的。到了如今,lambda已經隨處可見了,這多虧了JS的功勞。例如,
// A very simple function in six languages. function (a) { return a > 0; } // JS [](int a) { return a > 0; } // C++ (lambda (a) (> a 0)) ;; Lisp lambda a: a > 0 # Python a => a > 0 // C# a -> a > 0 // Java新的箭頭語法
ES6引入了新的箭頭函數編寫方式。
// ES5 var selected = allJobs.filter(function (job) { return job.isSelected(); }); // ES6 var selected = allJobs.filter(job => job.isSelected());當須要編寫一個簡單的單一參數函數時,能夠採用箭頭函數來書寫,標識名=>表達式。這樣就能夠省卻function和return的輸入,還有括號,分號等。
當須要編寫一個含有多個參數的函數時,只要把相關參數用括號包起來就行了。
// ES5 var total = values.reduce(function (a, b) { return a + b; }, 0); // ES6 var total = values.reduce((a, b) => a + b, 0);我認爲這是最簡潔的書寫格式。
箭頭函數的功用與Underscore.js和immutable等庫的功能相似,immutable的示例文檔中所有都是使用ES6來編寫的,所以使用了大量的箭頭函數。
除了函數樣式編寫,箭頭函數還能夠包含區塊語句而不單單是單一表達式。例如:
// ES5 $("#confetti-btn").click(function (event) { playTrumpet(); fireConfettiCannon(); });ES6的寫法爲:
// ES6 $("#confetti-btn").click(event => { playTrumpet(); fireConfettiCannon(); });this是什麼?
普通函數與箭頭函數有個微小的不一樣點。箭頭函數沒有本身的this值,其this值是經過繼承其它傳入對象而得到的。
JS是如何處理this的呢?這可不是個簡單的問題。其中不論函數有沒有真的須要處理this,函數都是會接收到的。你曾經寫過以下代碼嗎?
{ ... addAll: function addAll(pieces) { var self = this; _.each(pieces, function (piece) { self.add(piece); }); }, ... }這裏,其實你想寫的內聯函數僅僅是this.add(piece)。然而內聯函數不會繼承外部函數的this值。在內聯函數中,this的值是window或undefined。臨時變量self用於向內聯函數傳入外部this值。
在ES6中,若是遵循以下原則則可避免相似的作法:
使用非箭頭函數來處理由object.method()語法調用的方法。由於它們會接收到來自調用者的有意義的this值。
在其它場合都使用箭頭函數。
// ES6 { ... addAll: function addAll(pieces) { _.each(pieces, piece => this.add(piece)); }, ... }
何時使用箭頭函數
ES6箭頭函數在Firefox、Babel、Traceur、TypeScript等項目都有使用。在1936年,Alonzo Church和Alan Turing一塊兒開發了強大的數學計算機模型,人們習慣把它稱爲圖靈機。Church編寫了名爲λ-calculus的模型,當時他發現須要在系統使用到「函數」。
這是一個結合Church想法的「程序」示例:
fix = λf.(λx.f(λv.x(x)(v)))(λx.f(λv.x(x)(v)))
JS中可表示爲:
var fix = f => (x => f(v => x(x)(v))) (x => f(v => x(x)(v)));這個故事告訴咱們,箭頭函數能夠幫助打破陳規,重新的角度來思考問題。藉助箭頭函數,ES6將會變得更好更強大。(譯者:伍昆 責編:陳秋歌)
原文連接:ES6 In Depth: Arrow functions
本譯文遵循Creative Commons Attribution Share-Alike License v3.0