JavaScript中apply、call、bind的區(qū)別與用法

apply()、call()和bind()方法都是Function.prototype對(duì)象中的方法,而所有的函數(shù)都是Function的實(shí)例。三者都可以改變this的指向,將函數(shù)綁定到上下文中。

1. 語法

1.1 Function.prototype.apply()

apply() 方法調(diào)用一個(gè)函數(shù), 其具有一個(gè)指定的this值,以及作為一個(gè)數(shù)組(或類似數(shù)組的對(duì)象)提供的參數(shù)。
語法
func.apply(thisArg, [argsArray])

1.2 Function.prototype.call()

call() 方法調(diào)用一個(gè)函數(shù), 其具有一個(gè)指定的this值和分別地提供的參數(shù)(參數(shù)的列表)。
語法
fun.call(thisArg, arg1, arg2, ...)

1.3 Function.prototype.bind()

bind()方法創(chuàng)建一個(gè)新的函數(shù), 當(dāng)被調(diào)用時(shí),將其this關(guān)鍵字設(shè)置為提供的值,在調(diào)用新函數(shù)時(shí),在任何提供之前提供一個(gè)給定的參數(shù)序列。
語法
fun.bind(thisArg, 隊(duì)列or數(shù)組)()

2. 用法

這三個(gè)方法的用法非常相似,將函數(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

結(jié)果相同,call()和apply(),第一個(gè)參數(shù)都是要綁定上下文,后面的參數(shù)是要傳遞給調(diào)用該方法的函數(shù)的。不同之處在于,在給調(diào)用函數(shù)傳遞參數(shù)時(shí),apply()是數(shù)組,call()參數(shù)是逐個(gè)列出的。

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方法傳遞給調(diào)用函數(shù)的參數(shù)可以逐個(gè)列出,也可以寫在數(shù)組中。bind方法與call、apply最大的不同就是前者返回一個(gè)綁定上下文的函數(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

總結(jié)bind()的用法:該方法創(chuàng)建一個(gè)新函數(shù),稱為綁定函數(shù),綁定函數(shù)會(huì)以創(chuàng)建它時(shí)傳入bind()的第一個(gè)參數(shù)作為this,傳入bind()的第二個(gè)以及以后的參數(shù)加上綁定函數(shù)運(yùn)行時(shí)本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù)。

3. 應(yīng)用場(chǎng)景

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ù)組轉(zhuǎn)化為數(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都指向?qū)嵗?    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);
}
// 當(dāng)然也有更方便的 let log = console.log()

4. 總結(jié)

  • (1).三者都可以改變函數(shù)的this對(duì)象指向。
  • (2).三者第一個(gè)參數(shù)都是this要指向的對(duì)象,如果如果沒有這個(gè)參數(shù),默認(rèn)指向全局window。
  • (3).三者都可以傳參,但是apply是數(shù)組,而call是有順序的傳入。
  • (4).bind 是返回對(duì)應(yīng)函數(shù),便于稍后調(diào)用;apply 、call 則是立即執(zhí)行 。

5. 參考鏈接

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

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

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