亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 網站 > WEB開發 > 正文

深入淺出ES6(七):箭頭函數 Arrow Functions =>

2024-04-27 15:10:52
字體:
來源:轉載
供稿:網友

譯者按:ECMAScript 6已經正式發布了,作為它最重要的方言,javascript也即將迎來語法上的重大變革,InfoQ特開設“深入淺出ES6”專欄,來看一下ES6將給我們帶來哪些新內容。本專欄文章來自Mozilla Web開發者博客,由作者授權翻譯并發布。

箭頭符號在Javascript誕生時就已經存在,當初第一個JavaScript教程曾建議在HTML注釋內包裹行內腳本,這樣可以避免不支持JS的瀏覽器誤將JS代碼顯示為文本。你會寫這樣的代碼:

<script language="javascript"> <!-- document.bgColor = "brown"; // red // --> </script>

老式瀏覽器會將這段代碼解析為兩個不支持的標簽和一條注釋,只有新式瀏覽器才能識別出其中的JS代碼。

為了支持這種奇怪的hack方式,瀏覽器中的JavaScript引擎將<!--這四個字符解析為單行注釋的起始部分,我沒開玩笑,這自始至終就是語言的一部分,直到現在仍然有效,這種注釋符號不僅出現<script>標簽后的首行,在JS代碼的每個角落你都有可能見到它,甚至在Node中也是如此。

碰巧,這種注釋風格首次在ES6中被標準化了,但在新標準中箭頭被用來做其它事情。

箭頭序列-->同樣是單行注釋的一部分。古怪的是,在HTML中-->之前的字符是注釋的一部分,而在JS中-->之后的部分才是注釋。

你一定感到陌生的是,只有當箭頭在行首時才會注釋當前行。這是因為在其它上下文中,-->是一個JS運算符:“趨向于”運算符!

function countdown(n) { while (n --> 0) // "n goes to zero" alert(n); blastoff(); }

上面這段代碼可以正常運行,循環會一直重復直到n趨于0,這當然不是ES6中的新特性,它只不過是將兩個你早已熟悉的特性通過一些誤導性的手段結合在一起。你能理解么?通常來說,類似這種謎團都可以在Stack Overflow上找到答案。

當然,同樣地,小于等于操作符<=也形似箭頭,你可以在JS代碼、隱藏的圖片樣式中找到更多類似的箭頭,但是我們就不繼續尋找了,你應該注意到我們漏掉了一種特殊的箭頭。

<!--單行注釋
-->“趨向于”操作符
<=小于等于
=>這又是什么?

=>到底是什么?我們今天就來一探究竟。

首先,我們談論一些有關函數的事情。

函數表達式無處不在

JavaScript中有一個有趣的特性,無論何時,當你需要一個函數時,你都可以在想添加的地方輸入這個函數。

舉個例子,假設你嘗試告訴瀏覽器用戶點擊一個特定按鈕后的行為,你會這樣寫:

$("#confetti-btn").click(

jQuery的.click()方法接受一個參數:一個函數。沒問題,你可以在這里輸入一個函數:

$("#confetti-btn").click(function (event) { playTrumpet(); fireConfettiCannon(); });

對 于現在的我們來說,寫出這樣的代碼相當自然,而回憶起在這種編程方式流行之前,這種寫法相對陌生一些,許多語言中都沒有這種特性。1958年,Lisp首 先支持函數表達式,也支持調用lambda函數,而C++,Python、C#以及Java在隨后的多年中一直不支持這樣的特性。

現在截然不同,所有的四種語言都已支持lambda函數,更新出現的語言普遍都支持內建的lambda函數。我們必須要感謝JavaScript和早期的JavaScript程序員,他們勇敢地構建了重度依賴lambda函數的庫,讓這種特性被廣泛接受。

令人傷感的是,隨后在所有我提及的語言中,只有JavaScript的lambda的語法最終變得冗長乏味。

// 六種語言中的簡單函數示例 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());

當你只需要一個只有一個參數的簡單函數時,可以使用新標準中的箭頭函數,它的語法非常簡單:標識符=>表達式。你無需輸入functionreturn,一些小括號、大括號以及分號也可以省略。

(我個人對于這個特性非常感激,不再需要輸入function這幾個字符對我而言至關重要,因為我總是不可避免地錯誤寫成functoin,然后我就不得不回過頭改正它。)

如果要寫一個接受多重參數(也可能沒有參數,或者是不定參數、默認參數、參數解構)的函數,你需要用小括號包裹參數list。

// 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.js這樣的庫提供的函數工具,箭頭函數運行起來同樣美不可言。事實上,Immutable的文檔中的示例全都由ES6寫成,其中的許多特性已經用上了箭頭函數。

那么不是非常函數化的情況又如何呢?除表達式外,箭頭函數還可以包含一個塊語句?;叵胍幌挛覀冎暗氖纠?/p> // ES5 $("#confetti-btn").click(function (event) { playTrumpet(); fireConfettiCannon(); });

這是它們在ES6中看起來的樣子:

// ES6 $("#confetti-btn").click(event => { playTrumpet(); fireConfettiCannon(); });

這是一個微小的改進,對于使用了PRomises的代碼來說箭頭函數的效果可以變得更加戲劇性,}).then(function (result) { 這樣的一行代碼可以堆積起來。

注意,使用了塊語句的箭頭函數不會自動返回值,你需要使用return語句將所需值返回。

小提示:當使用箭頭函數創建普通對象時,你總是需要將對象包裹在小括號里。

// 為與你玩耍的每一個小狗創建一個新的空對象 var chewToys = puppies.map(puppy => {}); // 這樣寫會報Bug! var chewToys = puppies.map(puppy => ({})); //

用小括號包裹空對象就可以了。

不幸的是,一個空對象{}和一個空的塊{}看起來完全一樣。ES6中的規則是,緊隨箭頭的{被解析為塊的開始,而不是對象的開始。因此,puppy => {}這段代碼就被解析為沒有任何行為并返回undefined的箭頭函數。

更令人困惑的是,你的JavaScript引擎會將類似{key: value}的對象字面量解析為一個包含標記語句的塊。幸運的是,{是唯一一個有歧義的字符,所以用小括號包裹對象字面量是唯一一個你需要牢記的小竅門。

這個函數的this值是什么呢?

普通function函數和箭頭函數的行為有一個微妙的區別,箭頭函數沒有它自己的this值,箭頭函數內的this值繼承自外圍作用域。

在我們嘗試說明這個問題前,先一起回顧一下。

JavaScript中的this是如何工作的?它的值從哪里獲???這些問題的答案可都不簡單,如果你對此倍感清晰,一定因為你長時間以來一直在處理類似的問題。

這個問題經常出現的其中一個原因是,無論是否需要,function函數總會自動接收一個this值。你是否寫過這樣的hack代碼:

{ ... addAll: function addAll(pieces) { var self = this; _.each(pieces, function (piece) { self.add(piece); }); }, ... }

在這里,你希望在內層函數里寫的是this.add(piece),不幸的是,內層函數并未從外層函數繼承this的值。在內層函數里,this會是windowundefined,臨時變量self用來將外部的this值導入內部函數。(另一種方式是在內部函數上執行.bind(this),兩種方法都不甚美觀。)

在ES6中,不需要再hackthis了,但你需要遵循以下規則:

通過object.method()語法調用的方法使用非箭頭函數定義,這些函數需要從調用者的作用域中獲取一個有意義的this值。其它情況全都使用箭頭函數。 // ES6 { ... addAll: function addAll(pieces) { _.each(pieces, piece => this.add(piece)); }, ... }

在ES6的版本中,注意addAll方法從它的調用者處獲取了this值,內部函數是一個箭頭函數,所以它繼承了外圍作用域的this值。

超贊的是,在ES6中你可以用更簡潔的方式編寫對象字面量中的方法,所以上面這段代碼可以簡化成:

// ES6的方法語法 { ... addAll(pieces) { _.each(pieces, piece => this.add(piece)); }, ... }

在方法和箭頭函數之間,我再也不會錯寫functoin了,這真是一個絕妙的設計思想!

箭頭函數與非箭頭函數間還有一個細微的區別,箭頭函數不會獲取它們自己的arguments對象。誠然,在ES6中,你可能更多地會使用不定參數和默認參數值這些新特性。

借助箭頭函數洞悉計算機科學的風塵往事

我們已經討論了許多箭頭函數的實際用例,它還有一種可能的使用方法:將ES6箭頭函數作為一個學習工具,來深入挖掘計算的本質,是否實用,終將取決于你自己。

1936年,Alonzo Church和Alan Turing各自開發了強大的計算數學模型,圖靈將他的模型稱為a-machines,但是每一個人都稱其為圖靈機。Church寫的是函數模型,他的模型被稱為lambda演算(λ-calculus)。這一成果也被Lisp借鑒,用LAMBDA來指示函數,這也是為何我們現在將函數表達式稱為lambda函數。

但什么是lambda演算呢?“計算模型”又意味著什么呢?

用 幾句話解釋清楚很難,但是我會努力闡釋:lambda演算是第一代編程語言的一種形式,但畢竟存儲程序計算機在十幾二十年后才誕生,所以它原本不是為編程 語言設計的,而是為了表達任意你想到的計算問題設計的一種極度簡化的純數學思想的語言。Church希望用這個模型來證明普遍意義的計算。

最終他發現,在他的系統中只需要一件東西:函數。

這種聲明方式無與倫比,不借助對象、數組、數字、if語句、while循環、分號、賦值、邏輯運算符甚或是事件循環,只須使用函數就可以從0開始重建JavaScript能實現的每一種計算。

這是用Church的lambda標記寫出來的數學家風格的“程序”示例:

    fix = λf.(λx.f(λv.x(x)(v)))(λx.f(λv.x(x)(v)))

等效的JavaScript函數是這樣的:

var fix = f => (x => f(v => x(x)(v))) (x => f(v => x(x)(v)));

所以,在JavaScript中實現了一個可以運行的lambda演算,它根植于這門語言中。

Alonzo Church和lambda演算后繼研究者們的故事,以及它是如何潛移默化地入駐每一門主流編程語言的,已經遠超本文的討論范圍。但是如果你對計算機科學 的奠基感興趣,或者你只是對一門只用函數就可以做許多類似循環和遞歸這樣的事情的語言倍感興趣,你可以在一個下雨的午后深入邱奇數(Church numerals)和不動點組合子(Fixed-point combinator),在你的Firefox控制臺或Scratchpad中仔細研究一番。結合ES6的箭頭函數以及其它強大的功能,JavaScript稱得上是一門探索lambda演算的最好的語言。

我何時可以使用箭頭函數?

早在2013年,我就在Firefox中實現了ES6箭頭函數的功能,Jan de Mooij為其優化加快了執行速度。感謝Tooru Fujisawa以及ziyunfei(譯者注:中國開發者,為Mozilla作了許多貢獻)后續打的補丁。

微軟Edge預覽版中也實現了箭頭函數的功能,如果你想立即在你的Web項目中使用箭頭函數,可以使用Babel、Traceur或TypeScript,這三個工具均已實現相關功能。

我們的下一個話題是ES6中的一個非常陌生的特性,我們將一睹typeof x返回的全新的類型值。思考一下:不使用字符串如何命名?敬請期待我們下回分解,觀眾老爺們記得回來!

作者 Jason Orendorff ,譯者 劉振濤 發布于 2015年7月27日原文鏈接:http://www.infoq.com/cn/articles/es6-in-depth-arrow-functions


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久中文字幕| 亚洲国产成人在线播放| 国产精品国模在线| 欧美人成在线视频| 欧美猛交ⅹxxx乱大交视频| 国产一区视频在线播放| 国产精品国产三级国产aⅴ浪潮| 久久精品青青大伊人av| 久久久电影免费观看完整版| 这里只有精品视频在线| 欧美日韩成人网| 精品亚洲一区二区三区| 欧美亚洲在线播放| 亚洲国产精品成人va在线观看| 亚洲嫩模很污视频| 久久伊人免费视频| 九九热这里只有精品6| 国产精品激情av电影在线观看| 日韩在线视频免费观看高清中文| 成人性生交大片免费看视频直播| 爱福利视频一区| 精品丝袜一区二区三区| 欧美专区国产专区| 日韩男女性生活视频| 国产不卡视频在线| 色婷婷av一区二区三区久久| 国产日韩精品综合网站| 色偷偷偷亚洲综合网另类| 久久久久久久影院| 亚洲综合精品一区二区| 亚洲奶大毛多的老太婆| 国外成人性视频| 国产成人97精品免费看片| 久久亚洲精品一区二区| 亚洲2020天天堂在线观看| 欧美视频不卡中文| 日韩在线观看免费全集电视剧网站| 欧美日韩亚洲一区二| 成人免费激情视频| 国产国语videosex另类| 亚洲成人av资源网| 精品日韩中文字幕| 久久精品男人天堂| 久久久久久久久国产| 国产欧美精品va在线观看| 久久久久久尹人网香蕉| 97人洗澡人人免费公开视频碰碰碰| 国产成人91久久精品| 久久99热这里只有精品国产| 成人在线播放av| 中文字幕亚洲综合| 成人黄色免费在线观看| 亚洲午夜未删减在线观看| 亚洲欧洲偷拍精品| 最新国产精品拍自在线播放| 国产日韩欧美电影在线观看| 日韩av网址在线观看| 国产精品视频区1| 日本午夜在线亚洲.国产| 欧美洲成人男女午夜视频| 中文字幕亚洲激情| 神马久久久久久| 日韩美女免费线视频| 国产亚洲成av人片在线观看桃| 亚洲精品二三区| 欧美在线一区二区视频| 亚洲第五色综合网| 浅井舞香一区二区| 欧美巨大黑人极品精男| 亚洲男人天堂久| 国产精品美女主播| 亚洲国产高清高潮精品美女| 国内精品久久久久久| 国产精品成人免费视频| 久久精品人人爽| 中文字幕av一区二区| 精品国内自产拍在线观看| 久久99久久久久久久噜噜| 日韩日本欧美亚洲| 成人免费网站在线观看| 亚洲第一区第一页| 亚洲欧美成人一区二区在线电影| 亚洲精品免费在线视频| 不用播放器成人网| 欧美高清理论片| 高清亚洲成在人网站天堂| 91久久久久久久一区二区| 2019中文字幕在线免费观看| 欧美激情精品久久久久久久变态| 久久久免费观看视频| 久久精品视频免费播放| 亚洲人成在线电影| 精品亚洲一区二区三区| 福利一区福利二区微拍刺激| 欧美美女操人视频| 欧美www视频在线观看| 欧美在线视频免费观看| 亚洲人成在线观看| 久久久久久久亚洲精品| 91免费高清视频| 日韩电影免费观看在线观看| 91成人在线播放| 国产精品夫妻激情| 欧美日韩精品国产| 欧美激情网友自拍| 日韩av免费在线播放| 国产精品久久久av| 国产精品旅馆在线| 在线视频一区二区| 欧美日韩亚洲国产一区| 亚洲日本中文字幕| 久久亚洲成人精品| 精品久久久久久久久久久久久| 欧美在线视频一二三| 国产精品久久在线观看| 中文字幕日韩精品在线观看| 色多多国产成人永久免费网站| 精品国产一区二区三区久久| 亚洲精品在线看| 亚洲欧美在线看| 成人免费激情视频| 亚洲天堂第二页| 日韩美女在线观看一区| 久久久久久久久综合| 最近2019年日本中文免费字幕| 性夜试看影院91社区| 国产一区二区三区在线播放免费观看| 成人午夜在线影院| 久久久精品免费视频| 国产精品中文字幕久久久| 亚洲香蕉成视频在线观看| 日韩精品视频中文在线观看| 欧美电影第一页| 国内精品模特av私拍在线观看| 九九九久久久久久| 久久精品亚洲94久久精品| 7777精品久久久久久| 九九视频直播综合网| 久久免费视频在线| 亚洲国产欧美一区二区丝袜黑人| 亚洲第一二三四五区| 亚洲精品第一页| 中文字幕欧美亚洲| 国产精品88a∨| 操日韩av在线电影| 国产精品久久久av| 欧美做受高潮电影o| 成人夜晚看av| 久久国内精品一国内精品| 97精品国产97久久久久久免费| 国产69精品久久久久9999| 92版电视剧仙鹤神针在线观看| 青青在线视频一区二区三区| 欧美成人激情视频免费观看| 91久久精品久久国产性色也91| 国产在线观看精品| 国产精品麻豆va在线播放| 国产精品欧美亚洲777777| 亚洲午夜激情免费视频| 永久免费精品影视网站| 最新国产精品拍自在线播放| 精品国产31久久久久久| 九九热99久久久国产盗摄| 欧美激情综合亚洲一二区|