首頁  >  文章  >  web前端  >  javascript變數提升與閉包理解

javascript變數提升與閉包理解

亚连
亚连原創
2018-05-31 10:00:021376瀏覽

本篇文章給大家詳細分析了javascript變數提升和閉包的相關知識點,對此有興趣的朋友可以參考下。

我們先來看一個題目:

<script>
 console.log(typeof a)//undefined
 var a=&#39;littlebear&#39;;
 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 = &#39;global&#39;;
console.log(global); // global

function fn () {
  console.log(a); // undefined
  var a = &#39;aaa&#39;;
  console.log(a); // aaa
}
fn();

之所以會是以上的列印結果,是由於js的變數提升,實際上上面的程式碼是按照以下來執行的:

var global; // 变量提升,全局作用域范围内,此时只是声明,并没有赋值
console.log(global); // undefined
global = &#39;global&#39;; // 此时才赋值
console.log(global); // 打印出global
 
function fn () {
  var a; // 变量提升,函数作用域范围内
  console.log(a);
  a = &#39;aaa&#39;;
  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載入自訂的js檔案方法

vue頁面離開後執行函數的實例

vue輪播圖外掛程式vue-concise-slider的使用

#

以上是javascript變數提升與閉包理解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn