我們都知道,JS 中沒有的類的概念。 而 函數 則是 JS 中 很重要,很重要,很重要的一點。 理解 函數 也是非常有必要的。 先來看看 函數的定義。 如下: 上面講到了“函數的定義”,但是要怎麼理解“函數聲明”與“函數表達式”的不同呢? 讓我們看看什麼是“函數提升”?。 “函數提升”,會把當前作用 ...
我們都知道,JS 中沒有的類的概念。
而 函數 則是 JS 中 很重要,很重要,很重要的一點。
理解 函數 也是非常有必要的。
先來看看 函數的定義。
如下:
1 // 函數聲明 2 // 函數聲明不會立即調用,可以在你需要的時候調用它 3 function demo(){ 4 5 } 6 7 // 函數表達式, 該函數也可稱為匿名函數(無函數名) 8 // 該函數保存在一個變數中,可通過變數名調用該函數 9 var demo = funciton(){ 10 11 }; 12 13 // 構造函數(不推薦) 14 // 該方法會造成兩次解析代碼,且js中 很多都避免使用 new 關鍵字 15 var demo = new function(){ 16 17 }
上面講到了“函數的定義”,但是要怎麼理解“函數聲明”與“函數表達式”的不同呢?
讓我們看看什麼是“函數提升”?。
“函數提升”,會把當前作用域(作用域的問題,後面會講到)提升到前面的行為。這又代表著什麼好處呢。
舉個例子:
1 // 調用函數 2 test(); 3 4 // 函數聲明 5 function test(){ 6 alert('調用成功'); 7 } 8 9 // 調用函數 10 test(); // 報錯 11 12 // 函數表達式 13 var test = function(){ 14 alert('調用成功'); 15 }
我們知道代碼是從上而下的執行,一個變數若沒有聲明,則會拋出該變數未聲明的報錯信息。然後如上,為何可以如此呢?
這就是“函數提升”乾坤大羅移的時間了,由於“函數提升”的關係,因此調用函數,可以在函數聲明之前。
但是,但是,但是,使用函數表達式不能被提升。
說了這麼多,區別找到了嗎 ? 除了“函數提升”,在寫法上也有不同,這個細心的問題,就交給擁有慧眼的你了。
到這,我們已經瞭解了,函數的定義。也知曉了常用 調用函數的 方法。 接下來,我們聊聊 函數的參數
說到函數的參數,先看段代碼吧!
1 demo(2,3); // 2,3 實參 2 3 function demo(sum1,sum2){ // sum1,sum2 虛參 4 return sum1 + sum2; 5 }
函數參數分為:
- 顯示參數:在函數定義時列出(也稱虛參)
- 隱藏參數(arguments):在函數調用時傳遞給函數真正的值(也稱實參)
js 函數有個內置對象 arguments 對象,該對象包含了函數調用的參數數組。
參數規則:
- 函數定義時沒有對參數指定數據類型,也就是說,參數可以為任何類型
- 函數對隱藏參數(arguments)的個數沒有檢測,也就是說可以傳入比定義時參數的多
- 預設參數的值為 “undefined”
再,再接下來聊聊 函數的調用
也順帶著瞭解下 this 。
this 是什麼? this 是指向當前調用的對象。
1 // 作為一個函數調用 2 test(); 3 4 //當函數沒有被自身的對象調用時,this的值則會變成全局對象 5 function test(){ 6 alert(this); // 若在瀏覽器中打開,全局對象則是 window對象 7 } 8 9 // 作為一個對象的方法調用 10 var obj = { 11 sum1 : 10, 12 sum2 : 10, 13 sum : function(){ 14 console.log( sum1+sum2 ); 15 console.log( this ); 16 } 17 } 18 // obj對象調用該函數 ,this的值指向當前對象 obj 19 obj.sum(); // 20, obj 20 21 // 使用構造函數調用函數, 22 function test(name,age){ 23 this.name = name; 24 this.age = age; 25 } 26 // this 無任何值,this的值在調用實例化對象時(new object)創建 27 var obj = new test('Beck',21); 28 obj.name // Beck 29 30 // 自調用函數 31 (function(){ 32 console.log('自調用函數'); 33 })
還有一種方式,函數的方法調用。我們知道,函數在js中也是對象, 也有屬性和方法。
舉個例子
1 function test(sum1,sum2){} 2 // 統計的是參數的個數 3 test.length // 2
接下來,要瞭解的是,函數預定義的兩個方法 “calc()”,“apply()”;
這兩個方法,在於昨天總算明白一點,特此記錄下。
這兩個方法第一個參數,必須是 對象本身,也就是設置 this的值(參數為空時,預設使用全局對象)
而 calc() 與 apply() 的區別在於 第二個參數的不同、
apply() 的第二個參數,則是合成一個數組,而 calc() 的參數,則是全部顯現的定義(從第二個參數開始)
舉個例子
1 // 定義個對象 2 var obj = {}; 3 // 聲明一個函數 4 function test(sum1,sum2){ 5 console.log(sum1+sum2); 6 } 7 //使用apply方法 沒有自身對象調用 this的值提升為全局對象 8 test.apply(this,[10,10]); // this的值為window ,輸出 20 9 10 // 設置 this的值為 obj 11 test.apply(obj,[10,10]); // this的值為 obj. 輸出20 12 13 // 值的註意是是,即使只有一個參數,也必須使用 數組的方式傳遞 14 eg: test.apply(this,[10]); //不然會報錯 15 16 // 使用 calc 方法 同上,只是參數定義的方式不同 17 test.calc(this,10,10); // this的值為 window. 輸出20 18 test.calc(obj,10,10); // this的值為 obj ,輸出 20
其實,看到兩個方法差不多,可能到這,又要很多人糾結了,既然差不多,那麼該使用哪個方法好一點呢。
也沒必要糾結,使用哪一個方法,具體看你傳入的參數哪個方便,哪個方便就使用哪個。
記錄就這麼多,後續有更好的理解,會持續維護。如果有錯的地方,也希望你們指出來。
祝大家學習進步,共勉!