JavaScript作用域和this關鍵字



1.JS的作用域分為全局作用域和函數作用域

全局作用域內定義的變量可以在全局和函數體內訪問,函數作用域內定義的變量只能在自己的函數作用域內訪問。如果變量前沒有加var,無論在哪定義都會成為全局變量。

 1 //全局作用域
 2 var globalVal = "global";  //全局變量
 3 
 4 (function func (){
 5     //函數作用域
 6     var localVal = "local";
 7     globalVal2 = "global too";
 8     
 9     alert(globalVal);        //global
10     
11 })();
12 
13 alert(localVal);             //localVal is not defined
14 alert(globalVal2);           //global too 

上面代碼中的函數為立即執行函數,不經過調用就會自己執行,方便看測試結果,另一個重要作用稍后解釋。

另外,13行處報錯not defined和JS的undefined類型是完全不同的兩個概念。前者表示這個變量沒有聲明過,是不存在的或者不在可訪問的作用域內,程序會產生運行時錯誤並終止運行;后者是JS的基本數據類型,表示此變量聲明過,但未被定義,或被賦值為undefined,這個值可以顯示、比較、運算,不會報錯。

 

2.JS沒有塊級作用域

C++、Java等語言都有塊級作用域,如for循環while循環等,JS卻是沒有塊級作用域的!

1 for(var i=0;i<3;i++)
2 {    
3     alert(i);  //0,1,2 
4 } 
5 alert(i);      //3

上面5行代碼處i的值是3,也就是說 var i; 寫在for的里面和外面效果是一樣的。C++之所以無法在for結束之后訪問到i,是因為在一個塊級作用域執行完它的垃圾回收機制就啟動了,把塊級作用域內不用的變量釋放了。

 

3.構造函數創建函數的作用域是全局

 1 var globalVal = "global"; 
 2 
 3 (function func (){
 4     //函數作用域
 5     var localVal = "local";
 6     
 7     var func2 = new Function("alert(globalVal)");
 8     var func3 = new Function("alert(localVal)");  
 9     func2();    //global
10     func3();    //localVal is not defined
11 })();
12 
13 func2();        //func2 is not defined

上面代碼顯示,由構造函數創建的函數可以訪問到全局變量globalVal,但訪問不到局部變量localVal。第13行可能產生誤解,new Function創建的函數作用域是全局的,把它賦值給局部變量func2,外部訪問func2時未定義是正常的。

 

4.使用立即執行函數創建函數作用域

如1節所示,使用立即執行函數很大的用處是創建函數作用域,避免產生全局變量,因為全局變量重名可能產生覆蓋等一些難以排查的問題。

立即執行函數的4種寫法:

 1                 (function func(a){
 2                     var i = a;
 3                     console.log(i); 
 4                 })(1);
 5 
 6                 (function func(a){
 7                     var i = a;
 8                     console.log(i); 
 9                 }(2));
10 
11                 !function func(a){
12                     var i = a;
13                     console.log(i); 
14                 }(3);
15 
16                 void function func(a){
17                     var i = a;
18                     console.log(i); 
19                 }(4);

 

5.this關鍵字

this是一個總指向調用者的指針。以下是this指向的不同情況:

  1. 作為對象方法調用,this是對象 :point.move()
  2. 作為函數調用(包括立即執行函數),this是window :move()
  3. 作為內部函數,即聲明在函數中的函數,this是window that=this
  4. 作為構造函數調用,即用new,this指向新生成的對象

 node.js中沒有window對象,這種情況都指向null。

 

6.ES6箭頭函數中的this

this總是指向被調用者,再也不需寫var that=this這類代碼。

 


免責聲明!

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



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