es6中的一系列關於函數用法的變化是很是有趣的,在es6的新標準下,你能夠更加輕便地使用函數,而且能夠仿照面向對象編程的思想來使用函數,將函數轉化爲「類」。(這裏的類加了引號,緣由咱們會在後面的學習中解釋)下面就讓咱們來一塊兒看一看es6下的函數有哪些有趣的變化。javascript
箭頭函數是es6下實現的一種新的函數書寫方法。在過去的編程中,咱們若是實現一個將數組內的字符串所有變成大寫,須要這樣的匿名函數進行實現:java
const Marvel = ['spider man', 'iron man', 'thor', 'hulk', 'captain']; const UpperMarvel = Marvel.map(function (name) { return name.toUpperCase(); }); console.log(UpperMarvel); // Uppercase of all the elements in Marvel[]
如今,咱們能夠經過箭頭函數來實現這一過程了:es6
const Marvel = ['spider man', 'iron man', 'thor', 'hulk', 'captain']; const UpperMarvel = Marvel.map( name => name.toUpperCase() ); console.log(UpperMarvel);
能夠看到,咱們去掉了function關鍵字,去掉了參數的圓括號,函數體的花括號,以及return語句。直接採用: 參數 => 參數的操做,這一形式來代替以前冗長的匿名函數。 須要注意的是,咱們並非完全拋棄了圓括號和花括號,在如下狀況時,咱們須要召回咱們的括號兄弟:編程
請看下面這個例子:數組
const Marvel = ['spider man', 'iron man', 'thor', 'hulk', 'captain']; const UpperMarvel = Marvel.map( name => { name = name.toUpperCase(); return `${name} has ${name.length} characters in their name`; }); console.log(UpperMarvel);
這裏咱們須要對name先進行大寫處理,再經過模板字面量輸出,多個語句,此時就必須有花括號出現。而且,因爲咱們當前花括號內的操做再也不是一個單一表達式了,函數體必須由咱們制定返回值,所以,return語句也是必不可少的!閉包
提到this指針,還真是個很是頭大的事情,對於初學者來講,javascript的第一個難點可能就在這裏,不少人都不理解這個this指針究竟是什麼東西。我我的比較習慣把this理解爲「所在地」,或者「你如今所處於」的意思,也就是說,它就是一個表示上下文環境的標誌!咱們來回顧一下在通常的javascript函數中,this都有哪些用法。ide
(1)當咱們對某一對象調用方法的時候,例如Data.getName()
函數
此時getName()函數中的this就指向對象Data。限定了當前大環境是Data對象,那麼getName()獲得的沒準就是Data.name的值。學習
(2)Data1.getName().call(Data2),此時咱們的call()方法傳入了對象Data2,瞭解call()方法,你應該就明白這裏咱們雖然調用了 Data1的getName()方法,可是已經把this指向了Data2!this
(3)this指向全局對象
以上是this指針在以往普通函數中的使用。那麼在新的箭頭函數中,this指針的規則有什麼新的調整嗎? 不難發現,在過去的函數中,this指針的指向取決於「怎麼被調用,誰調用」,就像咱們前面提到的Data.getName()同樣,this指向Data。但在箭頭函數中,this的指向更加直接,就是當前箭頭函數的所在上下文環境! 咱們經過一個例子就能夠看出this指針在箭頭函數中的用法:
function Latte() { this.sugar = 0; this.milk = 0; } Latte.prototype.addSugar = function () { setTimeout(function () { this.sugar++; console.log('sugar added!'); }, 500); }; const latte1 = new Latte(); latte1.addSugar(); setTimeout(function () { console.log(latte1.sugar); // 0 }, 1000);
你可能會覺得這裏setTimeout函數中的this.sugar++已經給sugar屬性增長了啊!爲何仍是0呢,這個+1去哪裏了?讓咱們想一想前面提到的普通匿名函數中的this指針的狀況。注意這裏this指針出如今setTimeout的第一個參數匿名函數中,這意味着什麼?這個裏層的匿名函數的this指針,可和addSugar方法中的this指針不是一個東西哦!這個this指針自己是沒有制定上下文的,它會直接被指向全局對象,那麼這個+1就加給了全局對象中的sugar(實際上至關於undefined + 1 =NaN)。這裏咱們解決方法就是使用閉包,把addSugar的this指針**「塞進」**setTimeout的匿名函數中,好比經過創建一個新變量賦值爲this,再在裏層的匿名函數中使用這個變量代替this指針便可!
可是若是使用箭頭函數,狀況就不是上述這樣了。牢記咱們的箭頭函數中的this指針永遠指向當前所處函數的上下文!也就是你即使有一百個箭頭函數嵌套在一塊兒,最裏面的this指針同樣指向最外層的函數的上下文!咱們看看一樣的例子,換做匿名函數:
Latte.prototype.addSugar = function () { setTimeout( () => { this.sugar++; console.log('sugar added!'); }, 500); };
這裏咱們的sugar終於會+1了,緣由就是咱們的this指針會自動指向當前setTimeout所在的上下文,也就是addSugar的function的this內容,這樣就能夠找到咱們的latte1對象中的sugar屬性了!
在es6中咱們能夠給函數進行默認函數參數的設定,尤爲是和以前咱們講到的數組對象的解構結合起來的時候,你就會發現咱們能夠用很簡單的代碼實現一個參數靈活的函數!一個顯示咖啡裏面配料比重的函數:
function Latte(coffee = 30, sugar = 10, milk = 60){ return `this cup of latte contains ${coffee}% of coffee,${sugar}% of sugar and ${milk}% of milk`; }
對應的輸出以下:
console.log(Latte()); // this cup of latte contains 30% of coffee,10% of sugar and 60% of milk console.log(Latte(15)); // this cup of latte contains 15% of coffee,10% of sugar and 60% of milk console.log(Latte(15,25,45)); // this cup of latte contains 15% of coffee,10% of sugar and 60% of milk
這就是默然參數函數的用處,你再也不須要像以往同樣,分別討論參數的缺省狀況。如今你能夠考慮一下,若是咱們的參數包括數組和對象,那麼經過以前學到的解構,是否是能夠發揮更強大的做用?這個留給你本身去嘗試一下! 以上就是es6中的一些函數方面的總結。