apply()與call()的區別

來源:互聯網
上載者:User

標籤:擷取   哪些   var   str   nts   for   原型   上下   his   

想要深入瞭解 call()apply() 這兩個方法,那麼必須要Crowdsourced Security Testing道他們的基本作用:

改變對象的執行內容

什麼是執行內容?

我們在寫一個方法的時候,總是會用到一個關鍵字this,而this的指向就是我們這裡所說的執行內容(執行環境)

首先我們要知道,this指向的永遠是調用該方法的對象,如何證明this的指向就是當前對象呢?看下面這段代碼:

function func () {    this.a = 1;    console.log(this.a);}func();  // 1

代碼中方法執行後控制台輸出1,由於func是全域對象window下的一個方法,那麼調用該方法的對象就應該是全域對象window,所以this理論上指向的對象就應該是window

如果理論成立,而this.a==1,也就是說變數a是一個全域變數。在控制台上直接輸入awindow.a後斷行符號,會發現輸出了1,所以在func這個方法中,this的指向就是window

換個方式來驗證下:

var person = {    name: ‘xiao ming‘,    age: 18,    who: function () {        console.log( ‘my name is ‘ + this.name + ‘ , ‘ + this.age + ‘ years old‘ );        console.log( person === this);    }}person.who();// my name is xiao ming , 18 years old// true

上面這段代碼中who方法是person對象的一個屬性,被person對象調用,所以this的指向也就是person

call()apply()異同

在瞭解異同之前,先來搞清楚這兩個方法都是怎麼用的

基本使用

call()

function.call(obj[,arg1[, arg2[, [,.argN]]]]])
  • 調用call的對象必須是個函數function
  • call的第一個參數將會是function改變上下文後指向的對象,如果不傳,將會預設是全域對象window
  • 第二個參數開始可以接收任意個參數,這些參數將會作為function的參數傳入function
  • 調用call的方法會立即執行

apply()

function.apply(obj[,argArray])

call方法的使用基本一致,但是只接收兩個參數,其中第二個參數必須是一個數組或者類數組,這也是這兩個方法很重要的一個區別

數組與類數組小科普

數組我們都知道是什麼,它的特徵都有哪些呢?

  1. 可以通過角標調用,如 array[0]
  2. 具有長度屬性length
  3. 可以通過 for 迴圈和forEach方法進行遍曆

類數組顧名思義,具備的特徵應該與數組基本相同,那麼可以知道,一個形如下面這個對象的對象就是一個類數組

var arrayLike = {    0: ‘item1‘,    1: ‘item2‘,    2: ‘item3‘,    length: 3}

類數組arrayLike可以通過角標進行調用,具有length屬性,同時也可以通過 for 迴圈進行遍曆

我們經常使用的擷取dom節點的方法返回的就是一個類數組,在一個方法中使用 arguments關鍵字擷取到的該方法的所有參數也是一個類數組

但是類數組卻不能通過forEach進行遍曆,因為forEach是數組原型鏈上的方法,類數組畢竟不是數組,所以無法使用

那麼如何才能讓類數組能夠使用forEach呢?小夥伴們可以在看完本篇後自己思考一下哦

異同

相同點

都能夠改變方法的執行內容(執行環境),將一個對象的方法交給另一個對象來執行,並且是立即執行

不同點

call方法從第二個參數開始可以接收任意個參數,每個參數會映射到相應位置的func的參數上,可以通過參數名調用,但是如果將所有的參數作為數組傳入,它們會作為一個整體映射到func對應的第一個參數上,之後參數都為空白

function func (a,b,c) {}func.call(obj, 1,2,3)// function接收到的參數實際上是 1,2,3func.call(obj, [1,2,3])// function接收到的參數實際上是 [1,2,3],undefined,undefined

apply方法最多隻有兩個參數,第二個參數接收數組或者類數組,但是都會被轉換成類數組傳入func中,並且會被映射到func對應的參數上

func.apply(obj, [1,2,3])// function接收到的參數實際上是 1,2,3func.apply(obj, {    0: 1,    1: 2,    2: 3,    length: 3})// function接收到的參數實際上是 1,2,3
兩個方法該如何選擇?

跟簡單,根據你要傳入的參數來做選擇,不需要傳參或者只有1個參數的時候,用call,當要傳入多個對象時,用apply

或者,如果需要傳入的參數已經是一個數組或者類數組了,就用apply,如果還是單獨的需要逐個傳入的,可以考慮使用call(如果你不嫌麻煩的話 )

【其他用途——對象繼承】

由於可以改變this的指向,所以也就可以實現對象的繼承

function superClass () {    this.a = 1;    this.print = function () {        console.log(this.a);    }}function subClass () {    superClass.call(this);    this.print();}subClass();// 1

subClass通過call方法,繼承了superClassprint方法和a變數,同時subClass還可以擴充自己的其他方法

apply()與call()的區別

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.