面試的時候被問到 bind、call和apply的區別,當時腦袋似懂非懂,事後通過一個簡單的例子寫出來分享給大家
首先說一下三者的共同點
共同點:
- 都是用來改變函式的this物件的指向的。
- 第一個引數都是this要指向的物件。
- 都可以利用後續引數傳參。
至於不同點,用一個例子區分:
新建兩個物件,平板物件pad
和電腦computer
,只有pad
裡有介紹intro
方法
var pad={
name:"ipad2020",
color:"black",
price:"5999",
intro:function(){
console.log(`名稱:${this.name},顏色:${this.color},價格:${this.price}`)
},
};
var computer={
name:"iMac2020",
color:"white",
price:"16999",
};
複製程式碼
現在有個場景,需要computer
使用intro
方法輸出自己的資訊,但是computer
本身沒有這個方法,這個時候我們可以藉助call、 bind、 apply
,讓computer
呼叫pad
的intro
方法
//1.使用call()
pad.intro.call(computer)
//控制檯輸如下
名稱:iMac2020,顏色:white,價格:16999
複製程式碼
//2.使用apply()
pad.intro.apply(computer)
//控制檯輸如下
名稱:iMac2020,顏色:white,價格:16999
複製程式碼
//3.使用bind(),此時控制檯不會輸出任何東西,因為bind()的返回值是一個函式,我們需要再呼叫一下,在後面加個括號
pad.intro.bind(computer)()
//呼叫後控制檯輸如下
名稱:iMac2020,顏色:white,價格:16999
複製程式碼
此時,可以總結出第一個差別:
區別1:call和apply都是對函式的直接呼叫,而bind方法返回的仍然是一個函式,因此後面還需要()來進行呼叫才可以
繼續看,新建一個noteBook物件,與之前不同的是,noteBook
裡的intro
方法有兩個引數 company和date
var noteBook={
name:"MacBook2020",
color:"glod",
price:"10000",
intro:function(company,date){
console.log(`名稱:${this.name},顏色:${this.color},價格:${this.price},公司:${company},生產日期:${date}`)
}
}
複製程式碼
繼續用computer
呼叫noteBook
的intro
方法,不同的是,這次需要傳值
//1.使用call(),傳入引數
noteBook.intro.call(computer,"Apple","2020-03-17")
//控制檯輸出如下:
名稱:iMac2020,顏色:white,價格:16999,公司:Apple,生產日期:2020-03-17
複製程式碼
//2.使用bind(),傳入引數
noteBook.intro.bind(computer,"Apple","2020-03-17")()
//控制檯輸出如下:
名稱:iMac2020,顏色:white,價格:16999,公司:Apple,生產日期:2020-03-17
複製程式碼
//3.使用apply(),此時傳參方式不同於前兩個,需要用陣列的方式
noteBook.intro.apply(computer,["Apple","2020-03-17"])
//控制檯輸出如下:
名稱:iMac2020,顏色:white,價格:16999,公司:Apple,生產日期:2020-03-17
複製程式碼
區別2:call後面的引數與intro方法中是對應的,而apply的第二個引數是一個陣列,陣列中的元素是和intro方法中對應。而bind它可以像call那樣傳參
總結:
不同點:
- call和apply都是對函式的直接呼叫,而bind方法返回的是一個函式,後面需要加()來進行呼叫。
- call和bind可以直接跟引數,而apply需要用陣列的方式