bind创建的函数this在绑定时即固化且不可变,即使再bind、call或apply也无法更改;同时支持预设参数实现柯里化。

bind 不能“永久绑定”事件处理函数,它只返回新函数
很多人以为 bind 能让某个函数“从此永远以某 this 执行”,其实不是——它只是创建一个新函数,该函数调用时固定使用指定的 this 和前置参数。原函数不受影响,也不会自动注册到 DOM 上。
常见错误现象:
– 绑定后没赋值给变量或没传给 addEventListener,结果事件根本没响应
– 把 obj.handleClick.bind(obj) 写成 obj.handleClick.bind(obj)()(立即执行,而非传给事件系统)
– 在类中直接写 onClick={this.handleClick.bind(this)}(每次渲染都新建函数,破坏 React.memo 或 shouldComponentUpdate)
- 必须显式把绑定后的函数赋值或传递出去,例如:
button.addEventListener('click', handler.bind(obj)) - 如果要复用,建议提前绑定并缓存:
const boundHandler = handler.bind(obj),再传入事件监听 - 在 React 类组件中,推荐在构造函数里绑定:
this.handleClick = this.handleClick.bind(this),避免重复创建
替代方案:箭头函数 vs bind,谁更适合事件绑定
箭头函数能自动继承外层 this,看起来更简洁,但它每次渲染都会生成新函数;bind 同样会生成新函数(除非手动缓存)。两者在性能上没有本质区别,但行为不同。
使用场景:
– 简单回调、不依赖 this 的纯函数?直接传函数名(如 onClick={handleClick})更高效
– 需要传参且保持 this?bind 可前置参数:onClick={handler.bind(obj, 'id123')}
– 类组件中需访问实例属性?优先在构造函数中 bind,或改用箭头方法声明:handleClick = () => { ... }
-
bind支持预置多个参数,箭头函数需要闭包模拟:onClick={() => handler('id123', event)} -
bind(null, ...)可忽略this,只用于参数预置(此时this指向全局或undefined,取决于严格模式) - 在非 React 环境(如原生 DOM),
bind是最明确、兼容性最好的方式
removeEventListener 时必须传入 bind 返回的同一函数引用
这是最容易被忽略的坑:addEventListener 和 removeEventListener 必须传入**完全相同的函数引用**,否则无法移除。而每次调用 bind 都返回新函数,所以这样写一定失败:
el.addEventListener('click', fn.bind(obj));<br>el.removeEventListener('click', fn.bind(obj)); // ❌ 不生效
正确做法是保存绑定后的函数:
const boundFn = fn.bind(obj);<br>el.addEventListener('click', boundFn);<br>// ...<br>el.removeEventListener('click', boundFn); // ✅
- 不要在
addEventListener行内调用bind,除非你确定不需要移除 - 如果需动态绑定不同上下文,考虑用事件委托 +
dataset或闭包参数代替频繁绑定/解绑 - 现代写法可配合
AbortController(Chrome 88+):用signal自动清理,无需手动removeEventListener
bind 在严格模式和非严格模式下对 this 的处理差异
bind 对 this 的绑定是硬性的,但它的输入值在不同模式下表现不同——尤其当你传入 null 或 undefined 时。
比如:fn.bind(null),在非严格模式下,实际调用时 this 会被自动转为全局对象(window 或 global);严格模式下则真正保持 null。
- 浏览器环境默认非严格模式,Node.js 模块默认严格模式,行为可能不一致
- 若想确保
this为null,显式用fn.bind(null)并启用严格模式(加'use strict') - 更稳妥的做法是传一个空对象:
fn.bind({}),避免跨环境歧义
bind 还是箭头函数更容易出问题。










