在 JavaScript 中,`call`、`bind` 和 `apply`区别
在 JavaScript 中,call
、bind
和 apply
是函数对象的方法,用于显式绑定函数的 this
指向。它们的核心区别如下:
1. call
- 作用:立即调用函数,绑定
this
并逐个传递参数。 - 语法:
func.call(thisArg, arg1, arg2, ...)
- 特点:
- 第一个参数是
this
指向的对象。 - 后续参数按顺序传递。
- 第一个参数是
- 示例:
function greet(message) {console.log(`${message}, ${this.name}!`); }const person = { name: "Alice" }; greet.call(person, "Hello"); // 输出:Hello, Alice!
2. apply
- 作用:立即调用函数,绑定
this
并通过数组传递参数。 - 语法:
func.apply(thisArg, [argsArray])
- 特点:
- 第一个参数是
this
指向的对象。 - 第二个参数是数组或类数组对象(参数列表)。
- 第一个参数是
- 示例:
function sum(a, b) {return a + b + this.offset; }const context = { offset: 10 }; sum.apply(context, [3, 5]); // 返回 18(3+5+10)
3. bind
- 作用:返回一个绑定了
this
的新函数,不会立即执行,需手动调用。 - 语法:
func.bind(thisArg, arg1, arg2, ...)
- 特点:
- 可以预设参数(部分应用函数)。
- 绑定后的函数调用时可继续传参。
- 示例:
const person = { name: "Bob" };function logInfo(age, city) {console.log(`${this.name}, ${age}, lives in ${city}`); }const boundFunc = logInfo.bind(person, 30); // 绑定 this 和第一个参数 age boundFunc("New York"); // 输出:Bob, 30, lives in New York
核心对比表
方法 | 调用时机 | 参数形式 | 返回值 | 典型场景 |
---|---|---|---|---|
call | 立即执行 | 参数列表 | 无(函数结果) | 明确参数数量时 |
apply | 立即执行 | 数组或类数组 | 无(函数结果) | 参数数量动态变化(如数组计算) |
bind | 延迟执行 | 参数列表(可预设) | 新函数 | 需要绑定上下文但稍后调用时 |
关键区别
1. 执行时机
call
和apply
会立即执行函数。bind
返回一个新函数,需要后续手动调用。
2. 参数传递
call
逐个传递参数:func.call(obj, 1, 2)
。apply
通过数组传递参数:func.apply(obj, [1, 2])
。bind
支持预设参数:const newFunc = func.bind(obj, 1)
,调用时newFunc(2)
。
3. 返回值
call
和apply
返回原函数的执行结果。bind
返回一个绑定this
的新函数。
典型应用场景
-
call
和apply
:- 借用方法(如借用数组方法操作类数组对象):
const arrayLike = { 0: "a", 1: "b", length: 2 }; Array.prototype.push.call(arrayLike, "c"); // arrayLike 变为 {0: "a", 1: "b", 2: "c", length: 3}
- 动态参数传递:
Math.max.apply(null, [3, 1, 5]); // 返回 5
- 借用方法(如借用数组方法操作类数组对象):
-
bind
:- 事件处理函数绑定
this
:class Button {constructor() {this.text = "Click me";this.handleClick = this.handleClick.bind(this); // 绑定 this}handleClick() {console.log(this.text); // 正确指向 Button 实例} }
- 预设参数:
function multiply(a, b) { return a * b; } const double = multiply.bind(null, 2); // 预设 a=2 double(3); // 返回 6(2*3)
- 事件处理函数绑定
注意事项
- 严格模式:若绑定
this
为null
或undefined
,在非严格模式下会默认指向全局对象(如window
),严格模式下则为undefined
。 - 箭头函数:箭头函数的
this
由外层作用域决定,call
/apply
/bind
无法修改其this
指向。