前端基礎——call、apply、bind的實現
阿新 • • 發佈:2019-01-07
call方法的實現
Function.prototype.myCall = function (obj, ...args) {
if (typeof this !== 'function') {
throw new Error(this + '.call is not a function');
}
if (obj === null || obj === undefined) {
obj = window;
} else {
obj = Object(obj);
}
Object.prototype. fn = this; // 步驟1
let result = obj.fn(...args);
delete Object.prototype.fn;
return result;
}
很多人在步驟1那裡,寫的是obj.fn = this; 先不說覆蓋的問題,後面在執行obj.fn()時,函式裡面的this的確指向obj,但此時的obj裡面多了個fn屬性。
測試一下上面寫的。
window.a = 2;
let obj = {
a: 1,
b: 3
}
let addNum = function (...args) {
let sum = args.reduce((previous, current) => previous + current);
console.log(this, sum);
return this.a;
}
let res1 = addNum.call(obj, 1, 2, 3);
console.log(res1);
let res2 = addNum.myCall(obj, 1, 2, 3);
console.log(res2);
結果:
apply方法的實現
跟call方法相比,也就是接收引數的形式不同而已,apply以陣列的形式接收引數。
Function.prototype.myApply = function (obj, args) {
if (typeof this !== 'function') {
throw new Error(this + '.call is not a function');
}
if (obj === null || obj === undefined) {
obj = window;
} else {
obj = Object(obj);
}
Object.prototype.fn = this;
let result = obj.fn(...args);
delete Object.prototype.fn;
return result;
}
測試:
window.a = 2;
let obj = {
a: 1,
b: 3
}
let addNum = function (...args) {
let sum = args.reduce((previous, current) => previous + current);
console.log(this, sum);
return this.a;
}
let res1 = addNum.apply(null, [1, 2, 3]);
console.log(res1);
let res2 = addNum.myApply(null, [1, 2, 3]);
console.log(res2);
結果:
bind方法的實現
Function.prototype.myBind = function (obj, ...args) {
if (typeof this !== 'function') {
throw new Error(this + '.call is not a function');
}
if (obj === null || obj === undefined) {
obj = window;
} else {
obj = Object(obj);
}
let _this = this;
return function (...args1) {
let arg = args.concat(args1);
Object.prototype.fn = _this;
let result = obj.fn(...arg);
delete Object.prototype.fn;
return result;
}
}
測試:
window.a = 2;
let obj = {
a: 1,
b: 3
}
let addNum = function (...args) {
let sum = args.reduce((previous, current) => previous + current);
console.log(this, sum);
return this.a;
}
let res1 = addNum.bind(undefined, 1, 2, 3);
console.log(res1(4, 5));
let res2 = addNum.myBind(undefined, 1, 2, 3);
console.log(res2(4, 5));
結果: