bind返回新函数且可预设this与参数;call/apply立即执行,仅参数传入方式不同;手动实现bind需处理new调用、参数拼接及原型继承;避免在react渲染中频繁bind。

bind 会返回新函数,且 this 和参数都可预设
当你需要生成一个长期复用的、this 绑定固定的函数时,bind 是唯一选择。它不立即执行,而是返回一个新函数,后续调用时 this 始终指向你传入的第一个参数。
常见错误是误以为 bind 能覆盖箭头函数的 this —— 实际上箭头函数没有自己的 this,bind 对它完全无效。
-
fn.bind(obj, 1)返回的函数,无论在哪调用,this都是obj,第一个实参固定为1 - 多次
bind不会叠加:第二次bind无法改变第一次绑定的this(内部已用[[BoundThis]]封装) - 如果原函数用了
new调用,bind返回的函数仍可被构造,此时this指向新实例,而非bind传入的对象
call 和 apply 立即执行,区别只在参数传入方式
call 和 apply 的核心作用一模一样:指定 this 并立刻执行函数。唯一的差异就是第二个及之后的参数怎么传。
典型误用场景是混淆参数展开逻辑:比如想把数组当参数列表传给 Math.max,却写了 Math.max.call(null, [1,2,3]) —— 这样只会得到 NaN,因为 call 把整个数组当成了第一个参数。
-
func.call(thisArg, arg1, arg2):参数逐个列出 -
func.apply(thisArg, [arg1, arg2]):第二个参数必须是数组(或类数组),会被展开 - 现代写法中,
apply大量被扩展运算符替代,例如func(...args)已足够简洁,除非要兼容 IE
手动实现 bind 时要注意 new 调用的优先级
自己写 bind polyfill 时,最容易漏掉的是对 new 的支持。如果返回的绑定函数被 new 调用,它应该忽略预设的 this,转而让实例继承原函数的原型。
判断是否被 new 调用,不能只看 this 是否为原始值 —— 更可靠的方式是用 instanceof 检查调用时的 this 是否是当前函数的实例。
- 返回的绑定函数内部需用
if (this instanceof boundFn)分支处理构造调用 - 预设参数和调用时参数要正确拼接:
preArgs.concat(args),不是简单覆盖 - 必须显式设置
boundFn.prototype = fn.prototype,否则instanceof会失效(但注意不要直接赋值,应使用Object.create避免污染原原型)
什么时候不该用它们?警惕 this 误绑的隐性成本
频繁用 bind 绑定事件处理器(比如 onClick={this.handleClick.bind(this)})会导致每次渲染都新建函数,破坏 React.memo 或 shouldComponentUpdate 的浅比较效果。
在严格模式下,call/apply 传入 null 或 undefined 作为 thisArg,this 就真的是 null 或 undefined,不会自动转成全局对象 —— 这点常被忽略,导致非预期的报错。
- React 类组件中,更推荐在构造函数里
bind一次,或改用箭头方法 - Node.js 中某些回调函数(如
fs.readFile)的this默认是undefined,强行bind可能干扰底层逻辑 - 如果函数本身不依赖
this,硬加bind或call只是增加可读性负担,没实际收益
this」—— 它可能藏在闭包里、被中间件包装过、或是某个库约定的回调签名。先确认调用现场的 this 是什么,再决定动不动手。










