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 就已经正确指向了设定的对象。
相关推荐
于慨1 天前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
石小石Orz1 天前
油猴脚本实现生产环境加载本地qiankun子应用
前端·架构
从前慢丶1 天前
前端交互规范(Web 端)
前端
@yanyu6661 天前
07-引入element布局及spring boot完善后端
javascript·vue.js·spring boot
CHU7290351 天前
便捷约玩,沉浸推理:线上剧本杀APP功能版块设计详解
前端·小程序
GISer_Jing1 天前
Page-agent MCP结构
前端·人工智能
王霸天1 天前
💥别再抄网上的Scale缩放代码了!50行源码教你写一个永不翻车的大屏适配
前端·vue.js·数据可视化
小领航1 天前
用 Three.js + Vue 3 打造炫酷的 3D 行政地图可视化组件
前端·github
@大迁世界1 天前
2026年React大洗牌:React Hooks 将迎来重大升级
前端·javascript·react.js·前端框架·ecmascript
PieroPc1 天前
一个功能强大的 Web 端标签设计和打印工具,支持服务器端直接打印到局域网打印机。Fastapi + html
前端·html·fastapi