call & apply & bind -高级前端必考

JavaScript 中 call、apply 和 bind 的用法与区别

一、对比

方法 调用方式 参数传递方式 是否立即执行 优点 缺点 典型使用场景
call 立即调用 依次传递多个独立参数 灵活改变 this 指向并立即执行,方便传递多个已知参数 参数较多时代码冗长 对象方法调用、函数参数已知的情况
apply 立即调用 传递一个数组(类数组)作为参数 适合将数组或类数组作为参数传递,代码简洁 参数必须是数组或类数组 数组参数处理、类数组操作
bind 返回新函数 可预先设定 this 和部分参数 可创建新函数,预设 this 和参数,提高代码复用性和灵活性 创建新函数可能增加内存占用 需要预设上下文和参数的场景,如事件处理

二、call 方法

用法

call 方法会调用函数,并将函数内部的 this 指向指定的对象,同时可以传递参数给函数。

语法:

javascript 复制代码
function.call(thisArg, arg1, arg2, ...)

举例

javascript 复制代码
const person = {
  name: "John",
  greet: function(age, hobby) {
    console.log(`Hello, my name is ${this.name}. I am ${age} years old and I like ${hobby}.`);
  }
};

person.greet(30, "reading"); // 直接调用,this 指向 person
// Hello, my name is John. I am 30 years old and I like reading.

const anotherPerson = {
  name: "Jane"
};

person.greet.call(anotherPerson, 25, "cooking"); // 使用 call,this 指向 anotherPerson
// Hello, my name is Jane. I am 25 years old and I like cooking.

优点

  • 可以灵活地改变函数内部的 this 指向,调用函数并立即执行。
  • 能够方便地为函数传递多个参数,参数依次传递。(写的时候很爽,复用的时候太恶心)

缺点

  • 如果参数数量较多,在调用 call 时需要逐个列出参数,代码可能会显得冗长。(所以尽量用apply,因为apply和call的不同就是传参方式,apply中只传一个数据即可)

三、apply 方法 (重点,常用)

用法

apply 方法也用于调用函数,指定函数内部的 this 指向,但它接受一个数组(或类数组对象)作为函数的参数。

语法:

javascript 复制代码
function.apply(thisArg, [argsArray])

举例

javascript 复制代码
const numbers = [1, 2, 3, 4, 5];

const max = Math.max.apply(null, numbers); // 使用 apply,将数组元素作为参数传递给 Math.max
console.log(max); // 5

const person = {
  name: "John",
  greet: function(...args) {
    console.log(`Hello, my name is ${this.name}. I like ${args.join(", ")}.`);
  }
};

const hobbies = ["reading", "cooking", "hiking"];
person.greet.apply(person, hobbies); // 使用 apply 传递数组参数
// Hello, my name is John. I like reading, cooking, hiking.

优点

  • 适合将数组或类数组对象作为参数传递给函数,避免逐个列出参数,使代码更简洁。

缺点

  • 参数必须是一个数组或类数组对象,不能像 call 那样直接传递多个独立参数。(复用的时候很爽)

使用场景

  • 防抖、节流中,可以用apply来更改闭包中return出来的function的this指向,从而可以在方法函数中用this指向来添加业务逻辑

四、bind 方法

用法

bind 方法会创建一个新函数,并将新函数内部的 this 指向指定的对象。调用 bind 不会立即执行函数,而是返回一个新函数,这个新函数可以在后续被调用。

语法:

javascript 复制代码
const newFunction = function.bind(thisArg, arg1, arg2, ...)

举例

javascript 复制代码
const person = {
  name: "John",
  greet: function(time, ...hobbies) {
    console.log(`Good ${time}, my name is ${this.name}. I like ${hobbies.join(", ")}.`);
  }
};

const greetMorning = person.greet.bind(person, "morning");
greetMorning("reading", "cooking"); // Good morning, my name is John. I like reading, cooking.

const anotherPerson = {
  name: "Jane"
};

const anotherGreet = person.greet.bind(anotherPerson, "afternoon");
anotherGreet("hiking", "painting"); // Good afternoon, my name is Jane. I like hiking, painting.

优点

  • 可以预先设定函数的 this 指向和部分参数,创建一个新函数,这个新函数可以在之后被多次调用,提高代码的复用性和灵活性。
  • 在事件处理函数或定时器等场景中非常有用,可以提前绑定好上下文,避免在回调中手动设置 this。

缺点

  • 创建了一个新的函数,如果频繁使用可能会增加内存占用,相比之下 call 和 apply 是直接调用函数。

使用场景

  • 当需要预先设定函数的上下文和部分参数,但又不希望立即执行函数,而是稍后多次调用时。例如,在设置事件监听器时,提前绑定好对象的方法作为事件处理函数,这样在事件触发时,函数内部的 this 就已经正确指向了设定的对象。
相关推荐
西陵23 分钟前
Nx带来极致的前端开发体验——任务编排
前端·javascript·架构
大前端helloworld30 分钟前
从初中级如何迈入中高级-其实技术只是“入门卷”
前端·面试
笑鸿的学习笔记39 分钟前
JavaScript笔记之JS 和 HTML5 的关系
javascript·笔记·html5
东风西巷2 小时前
Balabolka:免费高效的文字转语音软件
前端·人工智能·学习·语音识别·软件需求
萌萌哒草头将军2 小时前
10个 ES2025 新特性速览!🚀🚀🚀
前端·javascript·vue.js
半夏陌离2 小时前
SQL 入门指南:排序与分页查询(ORDER BY 多字段排序、LIMIT 分页实战)
java·前端·数据库
whysqwhw3 小时前
鸿蒙工程版本与设备版本不匹配
前端
gnip3 小时前
http缓存
前端·javascript
我不只是切图仔3 小时前
我只是想给网站加个注册验证码,咋就那么难!
前端·后端