手写 bind 的核心逻辑是创建新函数并永久绑定 this 与预设参数,基础版用闭包保存 fn 和 args 并通过 apply 合并参数;完整版增加 new 调用支持,通过 this instanceof boundFn 判断调用方式,继承原函数原型并修正 constructor。

手写 bind 的核心逻辑
bind 的作用是创建一个新函数,这个新函数调用时的 this 被永久绑定到指定对象,并可预设部分参数(柯里化)。关键点有三个:固定 this、合并参数、支持 new 调用(即绑定函数可作为构造函数)。
基础版:只处理 this 和参数绑定
先忽略 new 场景,实现最简可用版本:
Function.prototype.myBind = function (context, ...args) {
const fn = this;
return function (...rest) {
return fn.apply(context, args.concat(rest));
};
};
- 用 闭包 保存原始函数
this(即fn)和预设参数args - 返回的新函数接收剩余参数
rest,调用时用apply合并所有参数并指定this - 注意:此时不支持
new myBoundFn()—— 因为普通函数无法区分是否被 new 调用
完整版:支持 new 调用(构造函数行为)
当绑定函数被 new 调用时,应忽略传入的 context,让实例继承原函数原型,并以新对象为 this 执行。
Function.prototype.myBind = function (context, ...args) {
const fn = this;
// 创建一个空构造函数用于继承原型
const boundFn = function (...rest) {
// 判断是否通过 new 调用:this 是 boundFn 的实例?
const isConstructing = this instanceof boundFn;
// 如果是 new 调用,this 指向新实例;否则指向 context
const finalThis = isConstructing ? this : context;
return fn.apply(finalThis, args.concat(rest));
};
// 继承原函数的 prototype,保证 new 调用能访问原型方法
boundFn.prototype = Object.create(fn.prototype);
// 修复 constructor 指向(非必须但更规范)
boundFn.prototype.constructor = boundFn;
return boundFn;
};
-
this instanceof boundFn是判断 new 调用的关键依据(内部通过原型链检测) -
Object.create(fn.prototype)确保新函数实例能访问原函数原型上的属性和方法 - 手动设置
constructor避免丢失构造函数引用
使用示例与验证
测试是否符合原生 bind 行为:
立即学习“Java免费学习笔记(深入)”;
function greet(greeting, punctuation) {
return `${greeting}, ${this.name}${punctuation}`;
}
const person = { name: 'Alice' };
const bound = greet.myBind(person, 'Hello');
console.log(bound('!')); // "Hello, Alice!"
// 测试 new 调用
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function () { return `Hi, I'm ${this.name}`; };
const BoundPerson = Person.myBind(null, 'Bob');
const instance = new BoundPerson();
console.log(instance.name); // "Bob"
console.log(instance.sayHi()); // "Hi, I'm Bob"
只要输出一致,说明手写 bind 已覆盖主要场景。


















