JavaScript中的apply()和call()

剛接觸 apply() 的時候總是模棱兩可,似懂非懂,公司的前輩說這個方法就是為了改變函數(shù)的 this 。具體到底是如何改變,在什么場景下改變呢?來好好梳理一下吧~

(一)語法:

Function.prototype.apply()

fun.apply(thisArg, [argsArray])

thisArg: 在fun函數(shù)運行時指定的this值,即這個參數(shù)將替換 fun 里面的 this 對象。
[argsArray]: 這個參數(shù)是一個數(shù)組,將作為參數(shù)傳給 fun。很神奇的是,它雖然是數(shù)組格式,但卻會先默默轉(zhuǎn)換成列表格式,再傳參給 fun 。

Function.prototype.call()

fun.call(thisArg[, arg1[, arg2[, ...]]])

thisArg: 在fun函數(shù)運行時指定的this值,這個參數(shù)將替換 fun 里面的 this 對象。
arg1, arg2, ...:傳給 fun 函數(shù)的參數(shù)列表。

(二)兩者的區(qū)別:

call() 方法接受的是若干個參數(shù)的列表,而 apply() 方法接受的是一個包含多個參數(shù)的數(shù)組。

(三)看幾個常用的使用場景:

示例一:

在調(diào)用方法的時候使用,改變 this 對象。

function Cat(){
}
Cat.prototype={ 
  food:"fish", 
  say: function(){ 
    console.log("I love "+this.food); 
  }
}
var blackCat = new Cat;
blackCat.say(); // say方法里面的this是Cat()

function Dog(){
}
Dog.prototype={
  food:"bone"
}
var blackDog = new Dog;
blackCat.say.apply(blackDog); // I love bone ,相當(dāng)于在這執(zhí)行了blackCat.say(),但是say方法里面的this被改變,變成了dog()

示例二:

在函數(shù)內(nèi)部使用, 調(diào)用其它對象的方法給自己使用,經(jīng)常會傳到參數(shù)。

function Person(name, age){
  this.name=name;  
  this.age=age;  
}

function Student(name, age, grade){ 
  Person.apply(this,arguments); // 相當(dāng)于在這執(zhí)行了Person(),只是Person里面的this變成了Student,arguments將作為參數(shù)傳給Person
  // call的寫法
  // Person.call(this, name, age);
  this.grade=grade;  
}

var student=new Student("zhangsan",21,"一年級"); 
console.log("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);
// name:zhangsan
// age:21
// grade:一年級

示例三:

在一個異步的函數(shù)中用于引入一個回調(diào)函數(shù)。

function aFun(cate, callback) {
  var self = this; 
  $.ajax(url)
  .done(function(){
    if (cate == 'success') {
      callback.call(self, arg); //在這里執(zhí)行 callback,arg 是傳給 callback 的參數(shù)
    }
  })
  .fail(function(){
    if (cate == 'failure') {
      callback.call(self, arg);
    }
  })
}

aFun('success', function(arg) {
  console.log('成功啦~')
})
aFun('failure', function(arg) {
  console.log('失敗了。。。')
})

(四)apply() 的妙用

利用了“apply的第二個參數(shù)值,是一個數(shù)組,可以自動轉(zhuǎn)換為一個參數(shù)列表”這一特性。

求一個數(shù)組中的最大值/最小值

var num = [10, 0, 3, 15];
console.log( Math.max(10, 0, 3, 15)); // Math.max方法的參數(shù)僅支持列表形式
console.log( Math.max.apply(null, num)); //第一個參數(shù)用null,因為沒有對象去調(diào)用這個方法,只需要把num作為參數(shù)傳入Math.max()方法,并得到返回的結(jié)果

合并兩個數(shù)組

var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
Array.prototype.push.apply(arr1, arr2); // Array.prototype.push() 方法的參數(shù)僅支持列表形式
console.log(arr1); //  [1, 2, 3, 4, 5, 6]
console.log(arr2); //  [4, 5, 6]

(五)什么時候用 apply(),什么時候用call()

綜上所述我們可以總結(jié)下這兩個方法的使用場景:

  • 如果只有一個參數(shù)時,用哪個方法都是一樣的。
  • 如果被調(diào)用的函數(shù)參數(shù)只支持列表形式,而現(xiàn)有的參數(shù)是數(shù)組形式,可以用apply() 巧妙的轉(zhuǎn)換。
  • 使用 apply() 時,要注意參數(shù)數(shù)組里的順序是否對得上,如果現(xiàn)有參數(shù)的順序不是要求的,這時候用 call() 指定參數(shù)傳入的順序。例如:
function Person(name, age){
  this.name=name;  
  this.age=age;  
}

function Student(age, name, grade){ 
  Person.apply(this,arguments); //  如果這時候用這種寫法就會出錯,
  Person.call(this, name, age); // 這時候用call,可以指定參數(shù)傳入的順序
  this.grade=grade;  
}

本文參考文章有:

Js apply 方法 詳解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容