apply()婚肆、call()和bind()方法都是Function.prototype對象中的方法租副,而所有的函數(shù)都是Function的實例。三者都可以改變this的指向较性,將函數(shù)綁定到上下文中附井。
1. 語法
1.1 Function.prototype.apply()
apply() 方法調用一個函數(shù), 其具有一個指定的this值讨越,以及作為一個數(shù)組(或類似數(shù)組的對象)提供的參數(shù)两残。
語法
func.apply(thisArg, [argsArray])
1.2 Function.prototype.call()
call() 方法調用一個函數(shù), 其具有一個指定的this值和分別地提供的參數(shù)(參數(shù)的列表)永毅。
語法
fun.call(thisArg, arg1, arg2, ...)
1.3 Function.prototype.bind()
bind()方法創(chuàng)建一個新的函數(shù), 當被調用時,將其this關鍵字設置為提供的值人弓,在調用新函數(shù)時沼死,在任何提供之前提供一個給定的參數(shù)序列。
語法
fun.bind(thisArg, 隊列or數(shù)組)()
2. 用法
這三個方法的用法非常相似崔赌,將函數(shù)綁定到上下文中意蛀,即用來改變函數(shù)中this的指向。
2.1 普通寫法
let me = {
name: "me",
sayHello: function (age) {
console.log("hello, I am", this.name + " " + age + " " + "years old")
}
}
let someone = {
name: "someone",
}
me.sayHello(24) // hello, I am me 24 years old
2.2 call 與apply方法的用法
me.sayHello.apply(someone, [24]) // hello, I am someone 24 years old
me.sayHello.call(someone, 24) // hello, I am someone 24 years old
結果相同健芭,call()和apply()县钥,第一個參數(shù)都是要綁定上下文,后面的參數(shù)是要傳遞給調用該方法的函數(shù)的慈迈。不同之處在于若贮,在給調用函數(shù)傳遞參數(shù)時,apply()是數(shù)組痒留,call()參數(shù)是逐個列出的谴麦。
2.3 bind()的用法
me.sayHello.bind(someone, 24)() // hello, I am someone 24 years old
me.sayHello.bind(someone, ([24])() // hello, I am someone 24 years old
bind方法傳遞給調用函數(shù)的參數(shù)可以逐個列出,也可以寫在數(shù)組中伸头。bind方法與call匾效、apply最大的不同就是前者返回一個綁定上下文的函數(shù),而后兩者是直接執(zhí)行了函數(shù)恤磷。因此面哼,以上代碼也可以這樣寫:
me.sayHello.bind(someone)(24) // hello, I am someone 24 years old
me.sayHello.bind(someone)([24]) // hello, I am someone 24 years old
總結bind()的用法:該方法創(chuàng)建一個新函數(shù),稱為綁定函數(shù)扫步,綁定函數(shù)會以創(chuàng)建它時傳入bind()的第一個參數(shù)作為this魔策,傳入bind()的第二個以及以后的參數(shù)加上綁定函數(shù)運行時本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調用原函數(shù)。
3. 應用場景
3.1 求數(shù)組中的最大和最小值
let arr = [1,2,3,89,46]
let max = Math.max.apply(null,arr)//89
let min = Math.min.apply(null,arr)//1
3.2將類數(shù)組轉化為數(shù)組
let trueArr = Array.prototype.slice.call(arrayLike)
3.3 數(shù)組追加
let arr1 = [1,2,3]
let arr2 = [4,5,6]
let total = [].push.apply(arr1, arr2) //6
// arr1 [1, 2, 3, 4, 5, 6]
// arr2 [4,5,6]
3.4 判斷變量類型
function isArray(obj){
return Object.prototype.toString.call(obj) == '[object Array]'
}
isArray([]) // true
isArray('dot') // false
3.5 利用call和apply做繼承
function Person(name,age){
// 這里的this都指向實例
this.name = name
this.age = age
this.sayAge = function(){
console.log(this.age)
}
}
function Female(){
Person.apply(this,arguments)//將父元素所有方法在這里執(zhí)行一遍就繼承了
}
let dot = new Female('Dot',2)
3.6 使用 log 代理 console.log
function log(){
console.log.apply(console, arguments);
}
// 當然也有更方便的 let log = console.log()
4. 總結
- (1).三者都可以改變函數(shù)的this對象指向锌妻。
- (2).三者第一個參數(shù)都是this要指向的對象代乃,如果如果沒有這個參數(shù),默認指向全局window仿粹。
- (3).三者都可以傳參搁吓,但是apply是數(shù)組,而call是有順序的傳入吭历。
- (4).bind 是返回對應函數(shù)堕仔,便于稍后調用;apply 晌区、call 則是立即執(zhí)行 摩骨。
5. 參考鏈接
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/call
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
- http://www.reibang.com/p/bc541afad6ee
- https://www.cnblogs.com/xljzlw/p/3775162.html