Function.prototype.mybind = function (context) {
if (typeof this !== "function") {
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = [].slice.call(arguments, 1),
self = this,
F = function () {},
fBound = function () {
return self.apply(
this instanceof F ? this : context || window,
aArgs.concat([].slice.call(arguments))
);
};
F.prototype = this.prototype;
fBound.prototype = new F();
return fBound;
};
call与apply
在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,也就是说为了改变函数体内部 this 的指向
var func = function (arg1, arg2) {};
func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])
基本实现:
Function.prototype.mycall = function (context) {
var content = context || window;
content.fn = this;
var args = [];
for (var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
// 这里 args 会自动调用 Array.toString() 这个方法。
var result = eval('content.fn(' + args + ')');
delete content.fn;
return result;
}
Function.prototype.myapply = function (context, arr) {
var context = context || window;
context.fn = this;
var result;
if (!arr) {
result = context.fn();
} else {
var args = [];
for (var i = 0, len = arr.length; i < len; i++) {
args.push('arr[' + i + ']');
}
result = eval('context.fn(' + args + ')')
}
delete context.fn
return result;
}
function add(c, d) {
return this.a + this.b + c + d;
}
const obj = {
a: 1,
b: 2
};
console.log(add.call(obj, 3, 4)); // 10
console.log(add.mycall(obj, 3, 4)); // 10
console.log(add.myapply(obj, [3, 4])); // 10