手写call方法的核心是改变函数this指向并立即执行:先处理thisArg(null/undefined转全局对象,基本类型转包装对象),再用Symbol作键挂载函数到上下文并调用,最后删除临时属性。

JavaScript 中手写 call 方法的核心是:**改变函数的 this 指向,并立即执行该函数**。关键在于利用对象的临时属性来“借用”函数,再通过该对象调用它,从而让函数内部的 this 指向指定的对象。
基本思路和注意事项
原生 call 接收第一个参数为 thisArg(即要绑定的 this),后续参数是传给目标函数的实参。手写时需注意:
- 若传入
null或undefined,在非严格模式下应指向全局对象(如window或globalThis);严格模式下保持原值 - 需要处理非对象类型的
thisArg(如数字、字符串、布尔值),通过Object()包装成对应包装对象 - 避免污染原对象,调用完要删除临时添加的方法
- 要正确传递多个参数(从第二个参数开始)
手写 call 的实现代码
以下是兼容常见场景的基础实现:
Function.prototype.myCall = function(thisArg, https://www.php.cn/link/1f1bf7748e7e06682e348b22a722266a) {
// 处理 thisArg:null/undefined → 全局对象(非严格模式),其他类型转对象
const context = thisArg == null ? globalThis : Object(thisArg);
<p>// 将当前函数(this)挂载到 context 上,用唯一 key 避免覆盖
const fnKey = Symbol('tempFn');
context[fnKey] = this;</p><p>// 执行函数并捕获返回值
const result = context<a href="https://www.php.cn/link/1f1bf7748e7e06682e348b22a722266a">fnKey</a>;</p><p>// 清理临时属性
delete context[fnKey];</p><p>return result;
};简单验证示例
测试一下是否生效:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
function greet(greeting, punctuation) {
return `${greeting}, ${this.name}${punctuation}`;
}
<p>const person = { name: 'Alice' };</p><p>console.log(greet.myCall(person, 'Hello', '!')); // "Hello, Alice!"✅ 正确绑定了 this,参数也按顺序传入,返回值无误。
补充说明:为什么用 Symbol 做 key?
用 Symbol('tempFn') 而不是字符串(如 'temp')是为了降低与用户自有属性名冲突的风险。虽然不能 100% 避免(比如对方也用了同名 Symbol),但在实际使用中足够安全。如果想更保守,也可用 Math.random() 或时间戳拼接字符串,但 Symbol 是更规范、轻量的选择。

















