
call、apply、bind都是用来改变函数this指向 的方法但它们在执行时机、参数形式、返回值上有明显区别。一、核心区别一览表方法是否立即执行参数形式返回值典型用途call✅ 是逐个传参函数执行结果一次性调用apply✅ 是数组/类数组函数执行结果数组参数bind❌ 否逐个传参新函数延迟执行、永久绑定二、逐个说明 示例1️⃣callfunction say(age, city) { console.log(this.name, age, city); } const person { name: Alice }; say.call(person, 18, Beijing); // Alice 18 Beijing✅特点立即执行参数一个一个传2️⃣applysay.apply(person, [18, Beijing]);✅特点立即执行参数放在数组中常用于数组展开、Math.max.apply(null, arr)⚠️注意apply第二个参数必须是数组或类数组3️⃣bindconst fn say.bind(person, 18); fn(Beijing); // Alice 18 Beijing✅特点不立即执行返回一个永久绑定 this 的新函数支持参数柯里化三、三者核心差异一句话总结call / apply 是“借方法立刻用”bind 是“造一个新函数慢慢用”。四、手写一个bind面试必考 ✅✅ 基础版不考虑 newFunction.prototype.myBind function (thisArg, ...args) { const originalFn this; return function (...newArgs) { return originalFn.apply(thisArg, [...args, ...newArgs]); }; };使用const fn say.myBind(person, 18); fn(Beijing);✅ 完整版支持new绑定⚠️关键点当 bind 返回的函数作为构造函数使用时this必须指向实例而不是绑定的对象。Function.prototype.myBind function (thisArg, ...args) { const originalFn this; function boundFn(...newArgs) { // 判断是否通过 new 调用 const isNewCall this instanceof boundFn; const context isNewCall ? this : thisArg; return originalFn.apply(context, [...args, ...newArgs]); } // 维护原型链否则 instance of 会失效 boundFn.prototype Object.create(originalFn.prototype); return boundFn; };五、验证 new 行为是否正确function Person(name) { this.name name; } Person.prototype.say function () { console.log(this.name); }; const BoundPerson Person.myBind(null, Tom); const p new BoundPerson(); console.log(p.name); // Tom console.log(p instanceof Person); // true ✅六、call / apply / bind 的 this 优先级当多种绑定同时存在时new bind call / apply 隐式绑定 默认绑定function foo() { console.log(this.a); } const obj { a: 1 }; const bar foo.bind(obj); bar(); // 1 bar.call({ a: 2 }); // 1bind 优先七、一句话终极总结问题答案共同点改变this指向最大区别是否立即执行bind 难点new 优先级 原型链手写 bind返回函数 apply new 判断