本篇文章給大家詳細分析了javascript變數提升和閉包的相關知識點,對此有興趣的朋友可以參考下。
我們先來看一個題目:
<script> console.log(typeof a)//undefined var a='littlebear'; console.log(a)//littlebear </script> <script> console.log(typeof a)//string var a=1; console.log(a)//1 </script>
第一個script裡可以看出var a 被提升到頂部,a = 'littlebear'被保留在原地。
第二個script,之所以不先印出undefined ,是因為a在上面已經被var宣告過,所以var a不會再被提升。
再看一個題目:
<script> console.log(a)//function a(){} var a=1; console.log(a)//1 function a(){} console.log(a)//1 </script>
可以看到function a(){}被提升到最頂端。說明函數的提升變數的提升
1.變數提升
#在ES6之前,JavaScript沒有區塊級作用域(一對花括號{}即為一個區塊級作用域),只有全域作
用域和函數作用域。變數提升即將變數宣告提升到它所在作用域的最開始的部分。
上個履歷的例子如:
console.log(global); // undefined var global = 'global'; console.log(global); // global function fn () { console.log(a); // undefined var a = 'aaa'; console.log(a); // aaa } fn();
之所以會是以上的列印結果,是由於js的變數提升,實際上上面的程式碼是按照以下來執行的:
var global; // 变量提升,全局作用域范围内,此时只是声明,并没有赋值 console.log(global); // undefined global = 'global'; // 此时才赋值 console.log(global); // 打印出global function fn () { var a; // 变量提升,函数作用域范围内 console.log(a); a = 'aaa'; console.log(a); } fn();
2.函數提升
js中建立函數有兩種方式:函數宣告式和函數字面量式。只有函數宣告才存在函數提升!如:
console.log(f1); // function f1() {} console.log(f2); // undefined function f1() {} var f2 = function() {}
之所以會有以上的列印結果,是由於js中的函數提升導致程式碼實際上是按照以下來執行的:
function f1() {} // 函数提升,整个代码块提升到文件的最开始 console.log(f1); console.log(f2); var f2 = function() {}
3.什麼是閉包
閉包是有權存取另一個函數作用域的變數的函數。
簡單的說,Javascript允許使用內部函數---即函數定義和函數表達式位於另一個函數的函數體內。而且,這些內部函數可以存取它們所在的外部函數中聲明的所有局部變數、參數和聲明的其他內部函數。當其中一個這樣的內部函數在包含它們的外部函數之外被呼叫時,就會形成閉包。
4.變數的作用域
要理解閉包,首先要理解變數的作用域。
變數的作用域無非就是兩種:全域變數和局部變數。
Javascript語言的特殊之處,就在於函數內部可以直接讀取全域變數。
其中內部函數中可以存取外部函數的變量,是因為內部函數的作用域鏈中包含了外部函數的作用域;
也可以理解為:內部函數的作用範圍輻射到了外部函數的作用範圍;
var n=999; function f1(){ alert(n); } f1(); // 999
另一方面,在函數外部自然無法讀取函數內的局部變數。
function f1(){ var n=999; } alert(n); // error
這裡有一個地方要注意,函數內部宣告變數的時候,一定要使用var指令。如果不用的話,你實際上聲明了一個全域變數!
function f1(){ n=999; } f1(); alert(n); // 999
5.閉包的寫法和用法
var Circle={ "PI":3.14159, "area":function(r){ return this.PI * r * r; } }; alert( Circle.area(1.0) );//3.14159
剛開始我沒意識到,這樣寫物件也是一種閉包,今天回頭想想,這就是閉包的經典用發啊!
6.使用閉包的注意點
1)由於閉包會讓函數中的變數都保存在記憶體中,記憶體消耗很大,所以不能濫用閉包,否則會造成網頁的效能問題,在IE中可能導致記憶體外洩。解決方法是,在退出函數之前,將不使用的局部變數全部刪除。
2)閉包會在父函數外部,改變父函數內部變數的值。所以,如果你把父函數當作物件(object)使用,把閉包當作它的公用方法(Public Method),把內部變數當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變數的值。
上面是我整理給大家的,希望今後對大家有幫助。
相關文章:
vue輪播圖外掛程式vue-concise-slider的使用
#以上是javascript變數提升與閉包理解的詳細內容。更多資訊請關注PHP中文網其他相關文章!