call、apply、bind的作用是改變this的指向,也就是函數執行時的上下文
apply 接收兩個參數,第一個參數是this的指向,第二個參數是函數接受的參數,以數組形式傳入。改變this指向後原函數會立即執行,且方法隻是臨時改變this指向一次。當第一個參數是Null、undefined時,預設指向window
call 與apply用法很像,不同的是從第二個參數是一個參數清單不是數組
bind和call很相似,但是改變this指向後不會立即執行,而是傳回一個永久改變this指向的函數(由指定this 和指定實參的原函數拷貝)
新函數 = fn1.bind(想要将this指向哪裡, 函數實參1, 函數實參2);
// 方式一:隻在bind中傳遞函數參數
fn.bind(obj,1,2)()
// 方式二:在bind中傳遞函數參數,也在傳回函數中傳遞參數
fn.bind(obj,1)(2)
總結
:apply、call、bind三者的差別在于:
- 三者都可以改變函數的this對象指向
- 三者第一個參數都是this要指向的對象,如果如果沒有這個參數或參數為undefined或null,則預設指向全局window
-
三者都可以傳參,但是apply是數組,而call是參數清單,且apply和call是一次性傳入參數,而bind可以分為多次傳入
bind是傳回綁定this之後的函數,apply、call 則是立即執
手寫bind: ①修改this指向 ②動态傳遞參數 ③相容new關鍵字
Function.prototype.myBind = function (context) {
// 判斷調用對象是否為函數
if (typeof this !== "function") {
throw new TypeError("Error");
}
// 擷取參數
const args = [...arguments].slice(1),
fn = this;
return function Fn() {
// 根據調用方式,傳入不同綁定值
return fn.apply(this instanceof Fn ? new fn(...arguments) : context, args.concat(...arguments));
}
}