call、apply、bind 作用是改變函式執行時的上下文,簡而言之就是改變函式執行時的 this 指向
區別
apply
apply 接受兩個引數,第一個引數是 this 的指向,第二個引數是函式接受的引數,以陣列的形式傳改變 this 指向後原函式會立即執行,且此方法只是臨時改變 this 指向一次
當第一個引數為 null、undefined 的時候,預設指向 window(在瀏覽器中)
call
call 方法的第一個引數也是 this 的指向,後面傳入的是一個引數列表
跟 apply 一樣,改變 this 指向後原函式會立即執行,且此方法只是臨時改變 this 指向一次
同樣的,當第一個引數為 null、undefined 的時候,預設指向 window(在瀏覽器中)
bind
bind方法和cal很相似,第一引數也是 this 的指向,後面傳入的也是一個引數列表(但是這個引數列表可以分多次傳入)
改變 this 指向後不會立即執行,而是返回一個永久改變 this 指向的函式
當然的,當第一個引數為 null、undefined 的時候,預設指向 window(在瀏覽器中)
不難看出三者之間的異同
- apply、call、bind 都能起到改變函式的 this 物件指向的作用,且當第一個引數為 null,undefined 時,預設指向 window;但 bind 可以起到永久修改的作用
- 三者都可以傳參,但是 apply是陣列,而call是引數列表,且apply和call 是一次性傳入引數,而 bind 可以分為多次傳入
bind 實現
Function.prototype.recodeBind = function (context) { if (typeof (context) !== 'function') { throw new TypeError('recodeBind needs to be a function'); } const args = [...arguments].slice(1) const fn = this return function Fn() { return fn.apply(this instanceof Fn ? new Fn(...arguments) : context, args.concat(...arguments)) } }