先放一個題外話:
node環境 親測結果: for(var i=0;i<5;i++){ setTimeout(function(){ console.log(i); },1000); } 每隔一秒輸出一個 5,共輸出五個5。 for(let i=0;i<5;i++){ setTimeout(function(){ console.log(i); },1000); } 每隔一秒輸出一個 數,0 1 2 3 4。
谷歌瀏覽器環境 親測結果: for(var i=0;i<5;i++){ setTimeout(function(){ console.log(i); },1000); } 先輸出一個10,而後每隔一秒輸出一個5,共輸出五個5。 for(let i=0;i<5;i++){ setTimeout(function(){ console.log(i); },1000); } 先輸出一個5,而後每隔一秒輸出一個數,依次是0 1 2 3 4。
谷歌瀏覽器環境 親測結果: var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; console.log(object.getNameFunc()()); 輸出 "The Window" console.log(object.getNameFunc().call(object)); 輸出 "My Object"
這個相對簡單一點: var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; console.log(object.getNameFunc()()); 輸出 "My Object"
這兩個更簡單: var name = "The Window"; var object = { name : "My Object", getNameFunc : ()=>{ console.log(this.name); } }; object.getNameFunc(); 輸出 The Window undefined var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ console.log(this.name); } }; object.getNameFunc(); 輸出 My Object
var name = 'global'; var obj = { name : 'obj', dose : function(){ this.name = 'dose'; return function(){ return this.name; } } } console.log(obj.dose()()); 輸出 global console.log(obj.dose().call(this)) 輸出 global console.log(obj.dose().call(window)) 輸出 global console.log(obj.dose().call(obj)) 輸出 dose 注意:把下面一行拆分(相似的均可以拆分) obj.dose().call(this) 拆分爲: var xxx = obj.dose(); xxx.call(this);
var name = 'global'; var obj = { name : 'obj', dose : function(){ this.name = 'dose'; return function(){ return this.name; }.bind(this) } } console.log(obj.dose().call(this)); 輸出 obj 注意:因爲return的function中用了bind,因此至關於固定了this,外邊再call什麼進來,也只是礙眼法而已。IE認爲在return中用bind不常見,兼容性也不高,因此上面內容能夠改寫以下: var name = 'global'; var obj = { name : 'obj', dose : function(){ var that = this; this.name = 'dose'; return function(){ return that.name; } } } console.log(obj.dose().call(this)); 輸出 obj
用處:閉包能夠用在許多地方。它的最大用處有兩個,一個是前面提到的能夠讀取函數內部的變量,另外一個就是讓這些變量的值始終保持在內存中。node
注意點:瀏覽器
1)因爲閉包會使得函數中的變量都被保存在內存中,內存消耗很大,因此不能濫用閉包,不然會形成網頁的性能問題,在IE中可能致使內存泄露。解決方法是,在退出函數以前,將不使用的局部變量所有刪除。閉包
2)閉包會在父函數外部,改變父函數內部變量的值。因此,若是你把父函數看成對象(object)使用,把閉包看成它的公用方法(Public Method),把內部變量看成它的私有屬性(private value),這時必定要當心,不要隨便改變父函數內部變量的值函數
來源:我將枕中記憶抹去任歲月浮光掠影性能