JS中的作用域以及全局變量的問題


一、 JS中的作用域

1、全局變量:函數外聲明的變量,稱為全部變量
 局部變量:函數內部使用var聲明的變量,稱為局部變量

在JS中,只有函數作用域,沒有塊級作用域!!!也就是說,if/for等有{}的結構體,並不能具備自己的作用域。

所以,函數外部不能訪問函數內部局部變量(私有屬性)。因為,函數內部的變量,在函數執行完畢以后,就會被釋放掉
2、使用閉包,可以訪問函數的私有變量!
JS中,提供了一種“閉包”的概念:在函數內部,定義一個子函數,子函數可以訪問父函數的私有便利。可以在子函數中進行操作,最后將子函數通過return返回

function func1(){ var num = 1; function func2(){ return num; } return func2; } var num = func1()(); console.log(num);

 

3、閉包的作用:
①可以在函數外部訪問函數的私有變量
②讓函數內部的變量可以始終存在於內存中,不會再函數調用完成后立即釋放。

function func1(){ var num = 1; function func2(){ return num; } return func2; } var num = func1()(); console.log(num);

 結果為1

 

二、 全局變量的問題

 

【錯誤原因!!】
代碼從上自下,執行完畢后,li的onclick還沒有觸發,for循環已經轉完!
而for循環沒有自己的作用域!所以循環5次,用的是同一個全局變量i!也就是在for循環轉完后,這個全局變量已經變成了5,那么在怎點li,點第幾個都會是5

var lis = document.getElementsByTagName("li"); for(var i=0; i<lis.length;i++){ lis[i].onclick = function(){ alert(i); } }

 

 

有三種辦法解決上述問題:

1、【使用閉包解決上述問題】
解決關鍵:函數具有自己的作用域!!在for循環轉一次,創建一個自執行函數。在美國自執行函數中,都有自己獨立的i,而不會被釋放掉。
所以for循環轉完以后,創建的5個自執行函數的作用域中,分別儲存了5個不同的i變量,也就解決了問題

var lis = document.getElementsByTagName("li"); for(var i=0; i<lis.length;i++){ !function(i){ lis[i].onclick = function(){ alert(i); } }(i); }

 

 

2、【使用let解決】
解決原理:let具有自己的塊級作用域,所以for循環轉一次,創建一個塊級作用域,思路與閉包相同

var lis = document.getElementsByTagName("li"); for(let i=0; i<lis.length;i++){ lis[i].onclick = function(){ alert(i); } }

 

 

3、【使用this解決】
解決原理:出錯的原則在於全局變量i在多次循環后被污染。那么在點擊事件中,就可以不使用i變量,而用this代替lis[i],這樣也就不會出現錯誤!

var lis = document.getElementsByTagName("li"); for(var i=0;i<lis.length;i++){ lis[i].onclick = function(){ console.log(this) } }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM