手写.call()
// 定义 Function.prototype 的自定义扩展方法 myCall
Function.prototype.myCall = function (context, ...args) {
// 检查 this 是否为函数类型,如果不是则抛出错误
if (typeof this !== "function") {
throw new TypeError("type error");
}
// 获取或设置执行上下文,默认为 window
var context = context || window;
// 保存原有 context.fn 的值(防止覆盖)
var temp = null;
if (context.fn) {
temp = context.fn;
}
// 将当前函数赋值给 context.fn,以便在该上下文中调用
context.fn = this;
// 在指定上下文中执行函数并收集结果
const res = context.fn(...args);
// 还原 context.fn 到原始值
if (temp) {
context.fn = temp;
} else {
delete context.fn;
}
// 返回函数执行的结果
return res;
};
手写.apply()
// 定义Function.prototype上的自定义方法myApply
Function.prototype.myApply = function (context, args) {
// 检查this是否为函数类型,如果不是则抛出错误
if (typeof this !== "function") {
throw new TypeError("type error");
}
// 如果args不是数组存在,则将其转换为数组形式
if (!Array.isArray(args)) {
args = Array.from(args);
}
// 设置执行上下文,默认为window对象
var context = context || window;
// 保存原始上下文fn属性(如果存在)
var temp = context.fn ? context.fn : null;
// 将当前函数赋值给上下文的fn属性
context.fn = this;
// 在指定上下文中执行函数,并将结果暂存到res变量中
const res = context.fn(...args);
// 还原上下文的fn属性
if (temp) {
context.fn = temp;
} else {
delete context.fn;
}
// 返回执行结果
return res;
};
手写.bind()
// 绑定函数的上下文和参数
Function.prototype.myBind = function (context, ...args) {
// 检查是否为函数类型
if (typeof this !== "function") {
throw new TypeError("type error");
}
// 保存参数和函数
const args0 = [...args];
const fn = this;
// 返回绑定后的函数
return function Fn(...args) {
// 如果是通过new调用,则创建一个新的实例
if (this instanceof Fn) {
return new fn(...args0, ...args);
}
// 否则,调用原函数并返回结果
return fn.call(context, ...args0, ...args);
};
};
参考:https://blog.youkuaiyun.com/weixin_51472145/article/details/132566180