快速理解JavaScript中apply()和call()的用法和用途

在學習apply()以前,咱們必須對this的做用和使用方法有所瞭解,能夠參考我前一篇文章《快速理解JavaScript中this的用法與陷阱》。固然若是你已經熟悉this的相關知識,那麼請直接往下看。編程

call()apply()的做用十分類似,只是參數類型上的差異,以適應不一樣的使用場景。它們都是爲了改變函數運行時的 context(上下文)而存在的,再說的直白一點,就是爲了改變函數內部 this 的指向。segmentfault

恩?什麼?我彷佛聽到你說改變this的指向??那就是說。。。數組

沒錯!這樣就能夠實現繼承啦!Exciting!app

看下面的代碼:函數式編程

如下代碼必須看過《瘋狂動物城》纔可看懂(逃)

function animal(name,food) {
   this.name = name,
    this.food = food,
   this.say = function() {
        console.log(name +" likes " + this.food + '.');
   }
}

function rabbit(name,food) {
   animal.call(this,name,food);
}

var Judy = new rabbit('Judy','carrot');

Judy.say();// >>> Judy likes carrot.

能夠看出,咱們聲明瞭一個叫Judy的對象,咱們並無在rabbit對象裏添加任何屬性和方法,可是咱們使用call()繼承了本來屬於animal的屬性和方法。就能夠作到animal函數全部能作到的事情。函數

這究竟是怎麼作到的呢?讓咱們來看看call()的參數:
第一個是一個對象,這個對象將代替Function類裏本來的this對象,咱們傳入的是this,記住,這個thisrabbit函數裏指的是將來將要實例化這個函數的對象(我知道這有些拗口),當聲明瞭Judy的時候,這個this指的就是Judy
除了第一個參數,後面全部的參數都是傳給父函數自己使用的參數。學習

apply()call()功能幾乎同樣,惟一的區別就是apply()第二個參數只能是數組,這個數組將做爲參數傳給原函數的參數列表argumentsthis

其實在實際開發中,JS 繼承的方法並不止這一種,使用原型鏈繼承是更加經常使用的方式,此外還有構造函數繼承,這裏不展開。而apply使用的場景,更多的使用在這樣一個場景:code

須要將數組轉化爲參數列表。對象

apply()的這個把數組轉化爲參數列表的特性,可讓它作一些有趣的事情。

例如,push()方法的參數只能是一個或者多個參數,而不能是一個數組,當咱們想要將數組B拼接到數組A後面時,傳統的作法是遍歷數組B,每循環一次就push進數組A後面,這樣就浪費了push()能夠傳多個參數的功能。
咱們能夠這樣作:

var list1 = [0,1,2];
var list2 = [3,4,5];
[].push.apply(list1,list2);

console.log(list1);// >>> [0,1,2,3,4,5]

看起來有點糊塗嗎?能夠這樣理解:
list1調用了屬於數組對象的push方法,這個push方法須要傳入一個參數列表,而剛好咱們有了list2這個數組類型的參數列表,實現了拼接操做。
第三行就至關於:

list1.push(3,4,5);

看,apply多麼神奇!一樣的,Math對象下的max()min()等方法都只支持參數列表而不是數組,能作什麼事情,你應該猜到了吧?

此外還有許多地方apply()的這個特性帶來不少便利:好比函數式編程中的currying(柯里化)apply()都有着不可或缺的做用。

既然說到這,那下一篇文章我就帶你們認識函數柯里化。今天有點晚了,先休息啦~

相關文章
相關標籤/搜索