區別: 指定this,call和apply執行函數,bind不執行
call
,apply
,bind
都是爲了解決this
的指向,call
和apply
都會執行函數,而bind
只是綁定this
不執行函數。call
和apply
接受參數方式不一樣,除了第一個參數都是指定this
,call
接受一個參數列表,apply
只接受一個參數數組。
var obj = {
value: 1
}
function foo(a, b) {
console.log(a, b)
console.log(this.value)
}
foo.call(obj, 1, 2)
foo.apply(obj, [1, 2])
// bind 只綁定
foo.bind(obj, 1, 2)
模擬實現call,apply,bind
實現思路
- 不傳入第一個參數,則默認爲
window
- 改變this指向,讓新的對象可以執行該函數。=》給新的對象添加一個函數,執行之後刪除
call
的實現
Function.prototype.myCall = function (context) {
var context = context || window; // 傳入的新對象
// 給新對象添加一個屬性(方法)
context.fn = this; // this 指向的是調用myCall方法的函數
// 取出剩餘參數
var args = [...arguments].slice(1);
var result = context.fn(...args); // 調用context.fn實則調用myCall方法的函數,但函數this指向了context
delete context.fn;
return result
}
apply
的實現
將call
方法實現中參數傳遞方式改爲數組形式
Function.prototype.myApply = function (context) {
var context = context || window; // 傳入的新對象
// 給新對象添加一個屬性(方法)
context.fn = this; // this 指向的是調用myCall方法的函數
// 剩餘參數 數組形式
var result;
if(arguments[1]) {
result = context.fn(...arguments);
} else {
result = context.fn();
}
delete context.fn;
return result
}
bind
的實現
this
指向,返回一個函數
Function.prototype.myBind = function (context) {
var context = context || window;
var _this = this;
var args = [...arguments].slice(1);
return function () {
_this.apply(context, args.concat(...arguments))
}
}