javascript變數提升和閉包理解,javascript變數提升

來源:互聯網
上載者:User

javascript變數提升和閉包理解,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); // undefinedvar global = 'global';console.log(global); // globalfunction fn () {  console.log(a); // undefined  var a = 'aaa';  console.log(a); // aaa}fn();

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

var global; // 變數提升,全域範圍範圍內,此時只是聲明,並沒有賦值console.log(global); // undefinedglobal = '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),這時一定要小心,不要隨便改變父函數內部變數的值。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.