You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写call、apply、bind的polyfill时,如何不借助三者绑定this指向?

实现思路

完全可以不依赖call/apply/bind实现this绑定,核心是利用JS原生的隐式this绑定规则:当函数作为对象的属性被调用时,函数内部的this默认指向该对象。

具体实现步骤

  • 处理绑定对象的边界情况:如果传入的绑定对象是null/undefined,默认指向全局对象;如果是字符串、数字等原始值,自动转为对应的包装对象
  • 用Symbol生成唯一的临时属性名,避免和目标对象的原有属性冲突
  • 将待执行的函数赋值给目标对象的这个临时属性
  • 调用目标对象上的临时方法,传入参数,此时方法内部的this会自动指向目标对象
  • 执行完成后删除目标对象上的临时属性,避免污染原对象
  • 返回函数执行的结果

完整代码

基础测试代码

const user = {
  firstName: "Christopher",
  lastName: "Nolan",
};

const fullName = function (place, country) {
  console.log(
    `${this.firstName} ${this.lastName} is from ${place}, ${country}.`
  );
};

自定义_call实现

Function.prototype._call = function (...args) {
  const func = this;
  // 处理绑定对象边界情况
  let ctx = args[0] ?? globalThis;
  ctx = Object(ctx);
  // 生成唯一临时属性,避免和对象原有属性冲突
  const tempFnKey = Symbol('temp_exec_fn');
  // 挂载函数到目标对象
  ctx[tempFnKey] = func;
  // 截取参数并执行
  const params = args.slice(1);
  const result = ctx[tempFnKey](...params);
  // 清理临时属性,不污染原对象
  delete ctx[tempFnKey];
  return result;
};

测试效果

// 执行后输出:Christopher Nolan is from London, UK.
fullName._call(user, "London", "UK");

如果需要兼容不支持Symbol的旧环境,可以将临时属性名替换为'__temp_fn_' + Date.now() + Math.random()这类随机字符串+时间戳的组合,即可降低和原有属性重名的概率。

内容的提问来源于stack exchange,提问作者Deva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 20:24:03