call和apply立即执行函数并改变this指向,区别在于参数传递方式;bind返回绑定后的新函数,可延迟调用且支持柯里化。

在javaScript中,call、apply 和 bind 都是用来改变函数执行时的上下文,也就是我们常说的 this 指向。虽然它们的功能相似,但在使用方式和返回结果上有明显区别。
1. call 与 apply:立即执行并改变 this 指向
call 和 apply 都会立即调用函数,并将函数内部的 this 绑定为指定对象。
它们的区别在于传参方式:
- call(thisArg, arg1, arg2, …):参数逐个传递
- apply(thisArg, [argsArray]):第二个参数是数组或类数组对象
示例:
function greet(greeting, punctuation) { console.log(greeting + ', ' + this.name + punctuation); } <p>const person = { name: 'Alice' };</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/c1c2c2ed740f" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">Java免费学习笔记(深入)</a>”;</p><p>greet.call(person, 'Hello', '!'); // 输出:Hello, Alice! greet.apply(person, ['Hi', '?']); // 输出:Hi, Alice?</p>
2. bind:返回新函数,不立即执行
bind 不会立即执行原函数,而是返回一个新函数,这个新函数的 this 被永久绑定到指定对象。
绑定后,无论之后如何调用该函数,this 都不会改变。
示例:
const boundGreet = greet.bind(person, 'Hey'); boundGreet('.'); // 输出:Hey, Alice.
bind 还支持柯里化(partial application),即预先传入部分参数。
3. 核心区别总结
- call / apply:立即执行函数,this 被临时绑定
- bind:返回绑定后的新函数,可延迟调用
- 参数传递:call 用逗号分隔,apply 用数组
4. 手动实现这三个方法
理解原理有助于深入掌握 this 机制。
实现 call
Function.prototype.myCall = function(context, ...args) { context = context || window; const fnSymbol = Symbol(); context[fnSymbol] = this; const result = context[fnSymbol](...args); delete context[fnSymbol]; return result; };
实现 apply
Function.prototype.myApply = function(context, args = []) { context = context || window; const fnSymbol = Symbol(); context[fnSymbol] = this; const result = context[fnSymbol](...args); delete context[fnSymbol]; return result; };
实现 bind
Function.prototype.myBind = function(context, ...bindArgs) { const fn = this; const boundFn = function(...args) { // 判断是否被 new 调用 return fn.apply( this instanceof boundFn ? this : context, bindArgs.concat(args) ); }; // 继承原型 if (this.prototype) { boundFn.prototype = Object.create(this.prototype); } return boundFn; };
注意:bind 的实现需要处理 new 调用的情况,此时 this 应指向新创建的实例,而不是绑定的对象。
基本上就这些。掌握 call、apply、bind 的区别和原理,对理解 javascript 的 this 机制和函数式编程非常有帮助。实际开发中,bind 常用于事件回调,call/apply 多用于借用方法或数组操作。手动实现能加深理解,面试也常考。不复杂但容易忽略细节。