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

为何需绑定通过同一对象调用的被遮蔽函数?

为什么直接引用Array.prototype.pop会触发this绑定错误?

先来看你遇到的代码场景:

Array.prototype.hook_pop = function(callback) { 
  // 方式一:可行
  var base_pop = this.pop.bind(this); 
  // 方式二:不可行,报错 "Uncaught TypeError: Cannot convert undefined or null to object"
  // var base_pop = this.pop; 
  this.pop = function() { 
    var ret = base_pop(); 
    callback(ret, this); 
    return ret; 
  } 
}

核心原因:函数的this是调用时决定的,不是定义时

你之前的理解有个小偏差:“除非显式绑定,否则this应指向调用方法的对象”——这句话没错,但前提是你是通过原对象调用方法。而当你把this.pop赋值给base_pop变量时,本质上是把Array.prototype.pop这个函数本身抽离出来了,和原数组实例断开了关联。

当你后续调用base_pop()时,这是一个独立函数调用,此时的this在非严格模式下会绑定到全局对象(浏览器里是window),严格模式下则是undefined。而原生的pop方法要求this必须是一个数组对象,否则就会抛出“无法将undefined/null转为对象”的错误——因为它内部要操作数组的length属性、访问元素,这些都依赖this是合法的数组。

为什么bind就可行?

bind方法会创建一个新的绑定函数,这个函数的this被永久固定为你传入的参数(也就是当前的数组实例)。不管你后续怎么调用这个绑定后的函数,它内部的this都不会变,始终指向原数组。所以调用base_pop()时,pop方法能正常拿到正确的this,自然就能正常执行。

举个更直观的例子辅助理解

const arr = [1,2,3];
// 直接取方法,和原对象断开
const rawPop = arr.pop;
rawPop(); // 报错,此时this不是arr

// 绑定this后
const boundPop = arr.pop.bind(arr);
boundPop(); // 正常执行,弹出3

总结

当你需要保存一个对象的方法并在后续独立调用时,如果这个方法的逻辑依赖原对象的this,必须通过bind显式绑定this,否则会丢失原对象的上下文,导致方法无法正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:55:13