1、call
// Function.prototype.call(this, arg1, arg2, …..)
// 可以改变this,并且传入参数,立刻执行,返回函数返回值
// Function.prototype.call()样例
function fun(arg1, arg2) {
console.log(this.name)
console.log(arg1 + arg2)
}
const obj = { name: '111' }
// 接受的是一个参数列表;方法立即执行
fun.call(obj, 1, 2)
Function.prototype.myCall = function (context = window, ...args) {
context = context || window; // 参数默认值并不会排除null,所以重新赋值
context.fn = this; // this是调用call的函数
const result = context.fn(...args);
delete context.fn; // 执行后删除新增属性
return result;
}
fun.myCall(obj, 1, 2)
2、bind
function fun(arg1, arg2) {
console.log(this.name)
console.log(arg1 + arg2)
}
const obj = { name: '111' }
Function.prototype.myApply = function (context = window, args = []) {
context = context || window; // 参数默认值并不会排除null,所以重新赋值
context.fn = this; // this是调用call的函数
const result = context.fn(...args);
delete context.fn;
return result;
}
fun.myApply(obj, [1, 2])
3、bind
function fun(arg1, arg2) {
console.log(this.name)
console.log(arg1 + arg2)
}
const obj = { name: '111' }
Function.prototype.myBind = function (context, ...args) {
debugger
const _this = this;
return function Bind(...newArgs) {
// 考虑是否此函数被继承
if (this instanceof Bind) {
return _this.myApply(this, [...args, ...newArgs])
}
return _this.myApply(context, [...args, ...newArgs])
}
}
fun.myBind(_this, 1, 2)()
手写 bind、call、apply
Function.prototype.MyCall = function (context) {
const args = [...arguments].slice(1);
context.fn = this;
const result = context.fn(...args);
delete context.fn;
return result;
}
Function.prototype.MyApply = function (context) {
const args = arguments[1] || [];
context.fn = this;
const result = context.fn(...args);
delete context.fn;
return result;
}
Function.prototype.MyBind = function (context) {
const args = [...arguments].slice(1);
return function () {
context.MyApply(context, args);
}
}