首頁 >web前端 >js教程 >js中call與apply的用法小結_javascript技巧

js中call與apply的用法小結_javascript技巧

WBOY
WBOY原創
2016-05-16 17:06:371055瀏覽

前天去面試,有個gg問了一些js知識,其中有一道call與apply用法的題目,儘管在365天前用過call方法,但當時還是沒能答上來,今天深入總結一下

call和apply,它們的作用都是將函數綁定到另一個物件上去運行

兩者的格式與參數定義:

call( thisArg [,arg1,arg2,… ] );       // 參數列表,arg1,arg2,...apply(thisArg 🎜>
上面兩個函數內部的this指針,都會被賦值為thisArg,這可實現將函數作為另外一個對象的方法運行的目的

一、call 的簡單用法

首先,我們先看個簡單的例子(call):


複製代碼 代碼如下:

 

  

call-apply
 

   


  
 






然後,運行結果如下:


global var
global var
member var
input text
func
member var
input text
func

func
測試環境:Google Chrome 10.0.648.45

最後,分析結果


1、全域物件window呼叫函數gFunc,
this指向window物件
,因此this.value為
global var

2、函數gFunc呼叫call方法,

this預設指向第一個參數window物件

,因此this.value也為global var

3、函數gFunc呼叫call方法,this預設指向第一個參數new mFunc(),即mFunc的物件,因此this.value為mFunc的成員變數member var

4、函數gFunc呼叫call方法,this預設指向第一個參數input text控件,即id='idTxt'的控件,因此this.value為input控件的value值 input text

5、函數func2呼叫call方法,this預設指向第一個參數func函數物件,因此this.value為this.a,即func

6、函數func2呼叫call方法,第二個參數屬於函數物件func2的參數,因此alert(x)為第二個參數func2

二、call 繼承用法與改良

js使用call模擬繼承


測試程式碼:

複製程式碼 程式碼如下:



 


  ;呼叫- 申請繼承<br> <br><br> 
  
預期的結果,應該是輸出baseA 成員和baseB 成員

,但實際輸出卻是

baseB 成員和baseB 成員


(已在IE9、8、6,Maxthon、Chrome、FF、Opera、Safari、360等瀏覽器測試過,結果皆為:baseB會員)
至此,機器是不會錯的,這就需要我們深入分析

我們可能很容易想到是這個原因的,這兩次都指向了baseB對象,但是推測真是這樣嗎?


為了取得實物,我們藉助chrome瀏覽器的調試工具,下斷點,進行調試,結果發現:

當呼叫

extend.showSelfA();時,此時的this指向extendAB(不是我們推測的兩次都指向baseB物件

真實原因是extendAB物件的成員變數成員在被

baseB.call(this);

實例化時,被baseB的成員成員覆蓋了,即extendAB的成員成員由baseA成員賦值為baseB member

當然,我們也可以對上面的baseA程式碼稍作修改,來驗證我們偵錯分析的正確性:


複製程式碼 程式碼如下:

function baseA()  // 基類A

{ this.memberA = "baseA member";   // 成員改成memberA,以區分BbaseBbase";   // 成員改成memberA,區分BbaseB的member this.showSelfA = function() {  window.alert(this.memberA);    //顯示memberA

 }

}

baseA 會員baseB 會員 結果和我們的預期一致,同時chrome調試資訊也驗證了我們的正確性:




繼承改良(原型)



以上模擬繼承方法,仔細分析不是最好的。
因為每次在函數(類別)中定義了成員方法,都會導致實例有副本,因此可以藉助prototype原型,進行改進
改進如下:


複製程式碼

程式碼如下:



 


  ;呼叫- 申請原型
 

 
  

 
  
 
  
 

運行結果如下:

obj: man和女人

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn