let是什麼 http://es6.ruanyifeng.com/#docs/letes6
最近,我寫了一篇關於syntax of Java’s IIFE pattern的文章,來解釋爲何咱們用如今的方式來寫當即執行函數表達式。少數的讀者批評文章過期了,都在爭論在ECMA 2015中介紹的塊級做用域變量使IIFE變得過期了。算法
偏偏相反,當即執行函數表達式一點也沒有過期!由於這個理由,我決定寫這篇後續文章來介紹一些當即執行函數表達式的常見用法。注意如下的列表是不完整的,因此若是你喜歡的用法沒有在文章出現,但願你不要有什麼很差的感受。windows
函數做用域 VS 塊級做用域瀏覽器
經過var關鍵字聲明的本地變量僅做用於當前閉包域,若是不存在這樣的一個閉包函數,那麼將會建立一個污染全局做用域的全局變量。爲了防止這種狀況出現,咱們可使用IIFE來建立一個包含有這個本地變量的函數。閉包
(function(){函數
varfoo= "bar";工具
console.log(foo);post
})();優化
foo;// ReferenceError: foo is not definedthis
目前的爭論是,咱們可使用在ECMA 2015介紹的塊級做用域變量來代替IIFE,以達到相同的效果。相比於函數級做用域,let和const關鍵字聲明的本地變量僅做用於當前所處的」塊」級域。
{
let foo= "bar";
console.log(foo);
}
foo;// ReferenceError: foo is not defined
然而,塊級做用域變量不是當即函數執行表達式的替代品。確實,若是支持ECMA 2015,let和const可以用來限制本地變量只在包含它的塊級做用域內使用。
若是,你在不支持ECMA 2015的環境(例如一些舊的瀏覽器)中執行你的Java代碼。你就不能使用let和const關鍵字來建立塊級做用域變量。你將不得不求助於之前經典的函數級做用域方法。
閉包和私有數據
IIFE的另外一個用法是爲局部變量提供一個封裝的做用域,在IIFE返回的函數中可以訪問該變量。這種方式即_a closure is created_容許函數訪問這個本地變量,即便這個函數在IIFE的詞法範圍以外執行時。
假設咱們要建立一個uniqueId函數,每次調用該函數時就會返回一個惟一的id(好比 「id_1」,「id_2」等)。在下面的IIFE中,記錄了一個私有的計數變量(count),每次調用計數函數uniqueId的時候,就會將count加一。咱們在IIFE中返回的另外一個函數,這個函數在調用時會返回一個新的標識符字符串。
constuniqueId= (function(){
let count= 0;
returnfunction(){
++count;
returnid_${count};
};
})();
console.log(uniqueId());// "id_1"
console.log(uniqueId());// "id_2"
console.log(uniqueId());// "id_3"
注意,在IIEF以外沒法訪問這個計數變量count。除了從IIEF中返回的函數,別人沒法讀寫該變量。這樣就能建立真正的私有狀態,它只能以受控的方式進行修改。revealing module pattern很是依賴於這種機制。
constcounter= (function(){
let counterValue= 0;
return{
increment(){
++counterValue;
},
get value(){
returncounterValue;
}
};
})();
counter.increment();
console.log(counter.value);// 1
counter.increment();
counter.increment();
console.log(counter.value);// 3
當使用IIFE來返回一個」封閉」一些本地變量來管理私有數據的函數時,let和const都不能替代它。
變量重命名
有時,你可能碰到一種狀況,你正在使用的兩個不一樣的庫暴露的全局變量名是相同的。例如,考慮一下你正在使用jQuery同時另外一個庫也指定了一個爲$的全局變量。
爲了解決命名衝突問題,能夠將一段代碼封裝在一個IIEF中,將一個全局變量(好比,jQuery)做爲參數傳入IIFE。在函數內部,就能夠以一個任意的參數名(好比,$)來訪問該參數值:
window.$= functionsomethingElse(){
// ...
};
(function($){
// ...
})(jQuery);
無論在外部做用域有什麼值指定給$,在IIFE中,這些值都會被」屏蔽」,$參數一直指向jQuery方法。
捕獲全局對象
Java代碼在不一樣環境執行時,你所使用的全局對象是不一樣的。當代碼在瀏覽器運行時,全局對象是windows。可是在Node.js中,全局對象是global。因爲在寫通用的Java代碼時,你確定不想硬編碼這兩個名字其中的任何一個,這時你就可使用一種」包裝」的方式就像下面這樣:
(function(global){
// ...
})(this);
不論是瀏覽器仍是Node.js的環境,global參數將會指定到對的全局對象上。若是想了解更多關於使用這種技巧來捕獲全局對象的細節內容,請移步this post by Todd Motto。
壓縮方面的優化
混疊變量名的方法也能夠用來優化代碼,這種方式使代碼可以被更有效的壓縮。舉例以下:
(function(window,document,undefined){
// ...
})(window,document);
一個Java壓縮工具例如UglifyJS能夠縮短函數的參數名爲單個字母的標識符
(function(w,d,u){
// ...
})(window,document);
更短標識符名會使文件的體積變得更小。然而,若是HTTP的返回內容經過Gzip或者Deflate進行壓縮,文件的大小已經被頗有效的壓縮了。所以,若是結合壓縮算法,壓縮技術的邊際收益會變得更小。因此本身權衡和比較返回內容的大小,較短的名字可能仍然是有做用的。