JS函數調用Javascript 函數有 4 種調用方式。每種方式的不同在於this的初始化。this關鍵字 一般而言,在Javascript中,this指向函數執行時的當前對象。但是this是保留關鍵字,並不能被修改。 調用函數,函數中的代碼在函數被調用後執行。 以上函數不屬於任何對象,但是在JS ...
JS函數調用
Javascript 函數有 4 種調用方式。每種方式的不同在於this的初始化。
this關鍵字
一般而言,在Javascript中,this指向函數執行時的當前對象。但是this是保留關鍵字,並不能被修改。
調用函數,函數中的代碼在函數被調用後執行。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"/> 5 <title></title> 6 <script> 7 function myFunction(a, b) { 8 return a * b; 9 } 10 myFunction(10, 2); //myFunction(10, 2) 返回20 11 </script> 12 </head> 13 </html>
以上函數不屬於任何對象,但是在JS中它始終預設是全局對象。
在HTML中預設的全局對象是HTML頁面本身,所以函數是屬於HTML頁面的。
在瀏覽器中的頁面對象是瀏覽器視窗。以上函數會自動變為window對象的函數。
所以myFunction()與window.myFunction()是一樣的效果。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"/> 5 <title></title> 6 <script> 7 function myFunction(a, b) { 8 return a * b; 9 } 10 window.myFunction(10, 2); //返回20 11 </script> 12 </head> 13 </html>
這個是調用JS函數常用的方法,但不是良好的編程習慣。
全局變數、方法和函數容易造成命名衝突的bug。
全局對象:
當函數沒有被自身的對象調用時,this的值就會變成全局對象。在瀏覽器中全局對象是window對象。所以以下代碼this值返回window對象。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"/> 5 <title></title> 6 <script> 7 function myFunction() { 8 return this; 9 } 10 window.myFunction(); //返回windo對象 11 </script> 12 </head> 13 </html>
函數作為全局對象調用,會使this的值變成全局對象。使用window對象作為一個變數容易造成程式崩潰。
函數作為方法進行調用:
在JS中可以將函數定義為對象的方法。
以下一段代碼創建了一個對象myObject,對象有兩個屬性firstName和lastName,以及一個方法fullName:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title></title> <script> function myObject() { firstName:'前端'; lastName:'技術'; fullName:function() { return this.firstName + " " + this.lastName; } } myObjec.fullName(); //返回前端 技術 </script> </head> </html>
fullName方法是一個函數。函數屬於對象。myObject是函數的所有者。
this對象擁有javascript代碼。以上代碼中this的值為myObject對象。
以下代碼修改了fullName方法並返回this值:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title></title> <script> function myObject() { firstName:'前端'; lastName:'技術'; fullName:function() { return this; } } myObjec.fullName(); //返回[object object](所有者對象) </script> </head> </html>
函數作為對象方法調用,會使得 this 的值成為對象本身。
使用構造函數調用函數:
如果函數調用前使用了new關鍵字,則調用了構造函數。
看起來就像創建了新的函數,但實際上JS函數是重新創建的對象:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"/> 5 <title></title> 6 <script> 7 function myFunction(arg1, arg2) { 8 this.firstName = arg1; 9 this.lastName = arg2; 10 } 11 12 // This creates a new object 13 var x = new myFunction("前端","技術"); 14 x.firstName; // 返回 "前端" 15 </script> 16 </head> 17 </html>
構造函數的調用會創建一個新的對象。新對象會繼承構造函數的屬性和方法。
構造函數中this關鍵字沒有任何的值。
this的值在函數調用時實例化對象的時候創建。
作為函數方法調用函數:
在JS中,函數是對象。JS函數有它的屬性和方法。
call()和apply()是預定義的函數方法。兩個方法可用於調用函數,兩個方法的第一個參數必須是對象本身。
call方法:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"/> 5 <title></title> 6 <script> 7 function myFunction(a, b) { 8 return a * b; 9 } 10 myFunction.call(myObject, 10, 2); // 返回 20 11 </script> 12 </head> 13 </html>
apply方法:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title></title> <script> function myFunction(a, b) { return a * b; } myArray = [10,2]; myFunction.apply(myObject, myArray); // 返回 20 </script> </head> </html>
兩個方法都使用了對象本身作為第一個參數。 兩者的區別在於第二個參數: apply傳入的是一個參數數組,也就是將多個參數組合成為一個數組傳入,而call則作為call的參數傳入(從第二個參數開始)。
在 JS嚴格模式(strict mode)下, 在調用函數時第一個參數會成為 this 的值, 即使該參數不是一個對象。
在 JS 非嚴格模式(non-strict mode)下, 如果第一個參數的值是 null 或 undefined, 它將使用全局對象替代。
通過 call() 或 apply() 方法可以設置 this 的值, 且作為已存在對象的新方法調用。