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

MDN bind方法Polyfill中arguments切片返回时消失的原因探究

解惑MDN bind方法Polyfill的参数疑问

嘿,我来帮你理清这个困惑!首先咱们先把MDN上经典的bind polyfill里你疑惑的核心代码段贴出来:

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      throw new TypeError('Function.prototype.bind - 要绑定的目标不是可调用函数');
    }

    // 这里的arguments是调用bind时传入的参数(除了第一个oThis)
    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          // 你疑惑的三元运算符就在这里
          return fToBind.apply(
            // 判断是否用new调用绑定后的函数,决定this指向
            this instanceof fNOP ? this : oThis,
            // 合并bind时的预设参数和调用绑定函数时的实时参数
            aArgs.concat(Array.prototype.slice.call(arguments))
          );
        };

    // 处理原型链继承
    if (this.prototype) {
      fNOP.prototype = this.prototype;
    }
    fBound.prototype = new fNOP();

    return fBound;
  };
}

你误解的核心:两个arguments不是一回事!

你觉得“错误拼接了重复的arguments”,其实是没注意到这两个arguments属于不同的函数作用域:

  • 第一个arguments(aArgs对应的那个):是你调用bind方法时传入的参数,比如func.bind(obj, 1, 2),这里的arguments是[obj, 1, 2],aArgs通过slice(1)拿到的是[1,2]——也就是你预设要传给原函数的参数。
  • 第二个arguments(concat里的那个):是你调用绑定后的函数时传入的参数,比如boundFunc(3,4),这里的arguments是[3,4]——也就是调用时临时传入的参数。

为什么没看到多余参数?

这段代码里的aArgs.concat(...)是把「bind时的预设参数」和「调用绑定函数时的实时参数」合并成一个数组,传给原函数。比如上面的例子,合并后是[1,2,3,4],原函数拿到的就是这组正确的参数,根本没有多余的内容。

关于你提到的“防止arguments泄露”

早期JS环境中,arguments对象和函数作用域强绑定,直接持有它可能导致内存泄漏或者意外的作用域穿透。用Array.prototype.slice.call(arguments)把它转成普通数组,既可以安全地操作参数,也避免了这些潜在问题——这就是你说的“安全特性”,它并没有掩盖什么bug,反而让代码更健壮。

举个实际测试例子

咱们写段代码验证一下:

function logArgs(...args) {
  console.log('拿到的参数:', args);
}

// 用上面的polyfill绑定预设参数
const boundLog = logArgs.bind(null, '预设参数A', '预设参数B');

// 调用绑定后的函数,传入实时参数
boundLog('实时参数X', '实时参数Y');

运行后控制台会输出:拿到的参数: ["预设参数A", "预设参数B", "实时参数X", "实时参数Y"],完全符合预期,没有多余参数。

所以你觉得的“bug”其实是对两个不同arguments的作用域误解啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:04:09