js-call、apply

來源:互聯網
上載者:User

標籤:

這裡主要就是做一些前人的總結,有時候會有自己的看法,首先把定義說一下

1、方法定義

call方法: 
文法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 
定義:調用一個對象的一個方法,以另一個對象替換當前對象。 
說明: 
call 方法可以用來代替另一個對象調用一個方法。call 方法可將一個函數的物件內容從初始的上下文改變為由 thisObj 指定的新對象。 
如果沒有提供 thisObj 參數,那麼 Global 對象被用作 thisObj。 

apply方法: 
文法:apply([thisObj[,argArray]]) 
定義:應用某一對象的一個方法,用另一個對象替換當前對象。 
說明: 
如果 argArray 不是一個有效數組或者不是 arguments 對象,那麼將導致一個 TypeError。 
如果沒有提供 argArray 和 thisObj 任何一個參數,那麼 Global 對象將被用作 thisObj, 並且無法被傳遞任何參數。

2、相同點和不同點

  1)相同點:本質都是一樣的,即兩個方法都是實現一個目的,看環境用哪個方法更合適;

  他們的第一個參數可以直接理解成方法的上下文(繼承也一樣,後面說一下繼承會提到),再說白一點,就是執行這個方法的時候,方法內部的this指向的就是第一個參數

  2)不同點:首先第二個選擇性參數的表現形式,call()第二參數是一個對象,可以有很多個;而apply第二個是一個數組,且最多隻有一個。

  主要表現在不同場合,選擇那個方法的問題。舉例說明一下(都來自網路):

    a)參數比較靈活:alert(Math.max(5,7,9,3,1,6));   //9  

    用call沒啥實質改變alert(Math.max.call(null,5,7,9,3,1,6));   //9

    用apply的話,可以把參數變成數組

    var arr = [5,7,9,3,1,6];

    alert(Math.max.apply(null,arr));

    因為arr作為參數的話,就活了,你可以在外界任意擴充長度,換做call的話,有多少得寫多少參數。apply還可以用arguments,原因是arguments本身數組形        式展現(注意arguments是類似數組的,但本質不是數組,只是有數組的性質:arg[n],arg.length等)

    b)apply根據第二個參數是資料群組的特點,可以做一些數組方面的應用:

    數組push:

    var arr1=[1,3,4];  
       var arr2=[3,4,5];  
       如果我們要把 arr2展開,然後一個一個追加到arr1中去,最後讓arr1=[1,3,4,3,4,5]   
       arr1.push(arr2)顯然是不行的。 因為這樣做會得到[1,3,4,[3,4,5]]  

    笨方法就是迴圈添加,這裡可以用Array.prototype.push.apply(arr1,arr2);

    也可以用concat方法

    數組concat降低緯度:

    var arr = [‘a‘,‘b‘,[‘c‘,‘d‘],‘e‘];

    想變成一維的,這時候可以用var rtn_arr = arr.concat.apply([],arr);//變成了 [‘a‘,‘b‘,‘c‘,‘d‘,‘e‘];

3、繼承

 function  Person(name,age,love){  
        this.name=name;  
        this.age=age;  
        this.love=love;  
        this.say=function say(){  
            alert("姓名:"+name);  
        }  
    }  

    //call方式  
    function student(name,age){  
        Person.call(this,name,age);  
    }  

    //apply方式  
    function teacher(name,love){  
        Person.apply(this,[name,love]);  
        //Person.apply(this,arguments); //跟上句一樣的效果,arguments  
    }  

   obj.call(this)這種沒有方法的直接調用call的寫法稱之為繼承,但本質上還是沒脫離定義的,這裡的obj實際上代表這構造方法,以上面例子說明:

  Person.call(this,name,age),Person代表的就是Person()這個函數的構造方法,實際上就是window.Person.call(this,name,age),window對象調用Person()方法,然後上下文(所謂的this)指向sudent,     這個時候Person()構造方法裡this實際上就是student,這也就是為什麼student會有了Person的屬性(所謂的繼承)。

  同時也能得出,這種繼承,是得不到原型賦值的屬性的,即Person通過prototype賦值的屬性,是無法用這個方法傳遞的

 

js-call、apply

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.