apply()
方法在指定 this
值和參數(參數以數組或類數組對象的形式存在)的狀況下調用某個函數。fun.apply(thisArg[, argsArray])
javascript
call()
方法在使用一個指定的this
值和若干個指定的參數值的前提下調用某個函數或方法。fun.call(thisArg[, arg1[, arg2[, ...]]])
java
二者基本一致,只有一個區別,就是call()
方法接受的是若干個參數的列表,而apply()
方法接受的是一個包含多個參數的數組。segmentfault
注意點thisArg
: 在 fun
函數運行時指定的 this
值。須要注意的是,指定的 this
值並不必定是該函數執行時真正的 this 值,若是這個函數處於非嚴格模式下
,則指定爲 null
或 undefined
時會自動指向全局對象(瀏覽器中就是window
對象,說明thisArg
能夠不傳),同時值爲原始值(數字,字符串,布爾值)的 this
會指向該原始值的自動包裝對象(Number,String,Boolean
)。數組
以call
爲例,apply
把後面參數轉化成數組格式便可瀏覽器
在調用一個存在的函數時,爲其指定一個全新的 this 對象(原函數的this對象這次調用
被覆蓋),而且能夠傳遞參數,app
function test(a) { console.log(this.one); console.log(a) } test.call({one:1},2) // 1 // 2 //咱們在test函數執行的時候綁定一個對象 {one:1} 和參數 2
調用父構造函數,實現繼承函數
function a(a) { this.a = a } function b(b) { this.b = b } //想要建立一個實例對象擁有a和b裏面的屬性 function c(a,b){ //至關於a,b函數執行了一次,因此屬性會被建立 a.call(this,a) b.call(this,b) } //效果等同於 function c(a,b){ this.a = a; this.b = b } var d = new c(1,2); d會同時用於a,b的屬性,這樣在涉及到不少屬性繼承時候就很方便 //c {a: 1, b: 1}
使用call方法調用匿名函數,引用官方示例,其實和1相似this
var animals = [ {species: 'Lion', name: 'King'}, {species: 'Whale', name: 'Fail'} ]; for (var i = 0; i < animals.length; i++) { (function (i) { this.print = function () { console.log('#' + i + ' ' + this.species + ': ' + this.name); } this.print(); }).call(animals[i], i); } // #0 Lion: King // #1 Whale: Fail
因爲call
方法須要窮舉全部須要傳遞的參數,因此只能在已知參數的狀況下使用,apply
則零活不少,可是接收參數的狀況是同樣的,apply能夠將數組形式默認轉化成一個參數列表 參數[a,b,c]會以(a,b,c)
的形式接收。
舉例來講:prototype
//比較一組數據大小 Math.max(9,2,4,6,7) // 9 Math.max([9,2,4,6,7]) // NaN //由於Math.max 方法不能接收一個數組 ,因此咱們能夠進行遍歷 var arr = [9,2,4,6,7],arr_len = arr.length,maxNumber = arr[0]; for(var i = 1 ;i< arr_len ;i++){ maxNumber = Math.max(maxNumber,arr[i]) } maxNumber // 9 //這樣可以達到效果,可是能夠有更方便高效的方法:用apply進行改造 Math.max.apply(null,[9,2,4,6,7]) //9 //通過apply轉化,Math.max這次執行的時候真正接收的參數是 (9,2,4,6,7) //因此相似這種原本須要寫成遍歷數組變量的任務 ,均可以用apply執行,Array.prototype.push也是
還有個 bind方法和這兩個很相似,能夠參考另外一篇內容,詳細說了bind方法
javascript原生一步步實現bind分析code
以上是我的理解,若是有誤,感謝指導!