bind生成的新函数不能被new调用,因其内部[[construct]]不可用,调用会抛typeerror;正确做法是用闭包、工厂函数或手动实现预设逻辑。

bind 生成的新函数为什么不能被 new 调用
因为 bind 返回的函数内部设置了 [[Construct]] 不可用标记,一旦用 new 调用,会直接抛出 TypeError: Function.prototype.bind called on an object that is not a function(不同引擎提示略有差异,但本质一致)。这不是 bug,是规范强制行为。
常见错误现象:想用 bind 预设构造器的部分参数,再通过 new 实例化——这行不通。
- 正确做法是改用闭包或工厂函数:
function createPerson(name) { return new Person(name, 'default-age'); } - 如果必须组合预设 + 构造,用
class或普通函数手动实现bind逻辑,别依赖原生bind - Chrome/Firefox 中可通过
Function.prototype.toString()观察bind函数输出为"function () { [native code] }",说明它不暴露可修改的构造逻辑
bind(thisArg, arg1, arg2) 的 this 和参数到底怎么绑定
bind 的第一个参数是硬绑定的 this,后续参数是“前置固定参数”,调用新函数时传入的参数会追加在它们后面。这个顺序不能反,也不支持跳过某参数占位。
使用场景:事件回调、定时器、Promise 回调中避免 this 丢失,或封装常用配置的工具函数。
-
obj.method.bind(obj, 'a')→ 调用时method('b')等价于obj.method('a', 'b') - 如果想跳过第一个参数只固定第二个,得手动写闭包:
x => obj.method('a', x),bind不支持undefined占位跳过 - 注意:箭头函数没有自己的
this,对箭头函数调用bind无效,this仍由外层决定
bind 与 call/apply 的核心区别在哪
bind 不执行函数,只返回一个新函数;call 和 apply 是立即执行,且不产生新函数。
性能影响:多次重复调用 bind(比如在 render 函数里)会持续创建新函数,触发 GC,也破坏 === 判断,导致 React 中 useCallback 失效或事件监听器重复绑定。
- 需要“一次绑定、多次复用”时才用
bind,比如类组件中this.handleClick = this.handleClick.bind(this)放在 constructor - 临时调用优先选
call/apply,更轻量,无内存开销 - ES6+ 更推荐用箭头函数或属性初始化语法(
handleClick = () => {...})替代bind,语义更清晰,也避免this绑定时机问题
bind 在严格模式和非严格模式下对 this 的处理有差异吗
没有差异。bind 的 this 绑定是硬性的,无论是否严格模式,只要传了非 null/undefined 的 thisArg,就一定生效;传 null 或 undefined,则非严格模式下会被转成全局对象(如 window),严格模式下保持 null/undefined。
容易踩的坑:在模块顶层或 IIFE 中误以为 bind(null) 能“清空” this,结果非严格模式下反而绑到了 window,引发意外副作用。
- 安全写法是显式传
undefined(严格模式下不变),或直接用箭头函数避免this问题 - Node.js 模块中默认严格模式,但 CommonJS 包裹函数内可能非严格,别依赖环境自动切换
- 检查方式:在绑定后立即
console.log(newFn.this)不行,得通过newFn.call(null)看实际执行时的this值
bind,而是什么时候不该用它——尤其是当团队已用上箭头函数、useCallback 或 class fields 时,还执着于 bind,往往意味着上下文理解有断层。










