手写 bind 方法需返回新函数,支持 this 绑定、参数预置、new 调用及原型继承;核心是判断 this 是否为新实例,若是则用 new 调用原函数,否则 apply 绑定 context 并合并参数。

JavaScript 中手写 bind 方法,核心是返回一个新函数,在调用时将指定的 this 值和预设参数绑定到原函数上,并支持后续传参(柯里化)以及作为构造函数调用(new 绑定优先级更高)。
基础功能:绑定 this 和初始参数
最简版本需做到:调用 fn.bind(obj, a, b) 返回一个函数,该函数执行时 this 指向 obj,且自动前置传入 a, b,再拼接后续调用时的参数。
实现要点:
- 保存原函数、目标
this、预置参数 - 返回的函数使用
apply或call调用原函数,合并参数 - 注意不能直接用箭头函数(会丢失
this动态性)
示例代码:
立即学习“Java免费学习笔记(深入)”;
Function.prototype.myBind = function (context, ...args) {
const fn = this;
return function (...innerArgs) {
return fn.apply(context, args.concat(innerArgs));
};
};
支持 new 调用(构造函数行为)
原生 bind 的关键特性:若返回函数被 new 调用,绑定的 this 失效,应以新创建的实例为 this。这需要判断调用方式。
判断逻辑:在返回的函数中,检查 this 是否为当前函数的实例(即是否通过 new 调用)。可用 instanceof 或更稳妥的 new.target(ES6+),但兼容老环境常用 instanceof。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
实现要点:
- 返回函数内部检测是否被
new调用 - 若是,忽略绑定的
context,用new fn(...)创建实例 - 若否,正常用
apply绑定
增强版代码:
Function.prototype.myBind = function (context, ...args) {
const fn = this;
// 创建一个空构造函数用于继承原型
const boundFn = function (...innerArgs) {
// 判断是否通过 new 调用:this 是 boundFn 的实例?
if (this instanceof boundFn) {
// new 调用:用原函数构造实例,传入所有参数
return new fn(...args, ...innerArgs);
}
// 普通调用:绑定 context 并执行
return fn.apply(context, args.concat(innerArgs));
};
// 保证 new 出来的实例能访问原函数原型上的方法
boundFn.prototype = Object.create(fn.prototype);
return boundFn;
};
注意原型链继承与 this 安全
手动绑定后,若不处理原型,new boundFn() 创建的实例将无法访问原函数原型上的属性或方法。
所以必须显式设置:
-
boundFn.prototype = Object.create(fn.prototype)—— 建立原型链 - 避免直接赋值
boundFn.prototype = fn.prototype(会污染原函数原型)
另外,为防 boundFn.prototype.constructor 指向错误,可选修复:
boundFn.prototype.constructor = boundFn;
小结:一个可用的最小完整实现
综合以上,一个兼顾功能、兼容性和安全性的手写 bind 如下:
Function.prototype.myBind = function (context, ...args) {
if (typeof this !== 'function') {
throw new TypeError('myBind must be called on a function');
}
const fn = this;
const boundFn = function (...innerArgs) {
if (this instanceof boundFn) {
return new fn(...args, ...innerArgs);
}
return fn.apply(context, args.concat(innerArgs));
};
boundFn.prototype = Object.create(fn.prototype);
boundFn.prototype.constructor = boundFn;
return boundFn;
};
它覆盖了普通绑定、参数预置、new 调用、原型继承四大核心场景,已接近原生行为。

















