js call 实现
理解 call 方法的作用
call 是 JavaScript 中函数对象的一个方法,用于显式指定函数执行时的 this 值,并传递参数列表。它的核心功能是改变函数的上下文(即 this 的指向),同时支持参数传递。
手动实现 call 的步骤
-
将函数挂载到目标对象上
通过为目标对象动态添加一个属性(例如_fn),将当前函数赋值给该属性。这样可以通过对象方法的形式调用函数,从而绑定this。 -
执行函数并传递参数
使用扩展运算符(或arguments处理)获取传入的参数列表,并以对象方法的形式调用函数,此时this自然指向目标对象。 -
清理临时属性并返回结果
执行完成后删除临时添加的属性,避免污染对象,并返回函数执行结果。
代码实现
Function.prototype.myCall = function(context, ...args) {
// 默认绑定到全局对象(非严格模式)或 undefined(严格模式)
context = context || (typeof window !== 'undefined' ? window : global);
// 将当前函数(this)挂载到目标对象上
context._fn = this;
// 执行函数,此时 this 指向 context
const result = context._fn(...args);
// 删除临时属性
delete context._fn;
return result;
};
使用示例
function greet(message) {
console.log(`${message}, ${this.name}`);
}
const person = { name: 'Alice' };
greet.myCall(person, 'Hello'); // 输出: "Hello, Alice"
关键点说明
this的绑定:通过将函数作为目标对象的方法调用,实现this的显式绑定。- 参数处理:使用剩余参数
...args收集所有传入的参数,避免手动处理arguments。 - 兼容性:默认绑定到全局对象(如浏览器中的
window或 Node.js 中的global),但严格模式下可能为undefined。
边界情况处理
- 原始值绑定:若
context是数字、字符串等原始值,需通过Object(context)转为对象。 - 函数无返回值:直接执行并删除临时属性,不影响原有逻辑。
改进后的完整实现:
Function.prototype.myCall = function(context, ...args) {
context = context ? Object(context) : (typeof window !== 'undefined' ? window : global);
const key = Symbol('_fn'); // 使用 Symbol 避免属性冲突
context[key] = this;
const result = context[key](...args);
delete context[key];
return result;
};






