当前位置: 首页 > news >正文

JavaScript的call和apply

在 JavaScript 中,.call().apply() 都是 Function 原型上的方法,用于改变函数执行时的上下文对象(即 this 指向),它们的区别仅在于参数传递的形式不同。下面结合几个常见场景,说明它们的实际应用。


1. 基本语法

func.call(thisArg, arg1, arg2,);
func.apply(thisArg, [arg1, arg2,]);
  • thisArg:调用时函数内部 this 应该指向的对象。
  • 参数列表call 是逗号分隔的参数序列;apply 是一个数组(或类数组)一次性传入。

2. “借用”其它对象的方法

有时候 A 对象没有某个方法,但 B 对象有,想让 A 使用 B 的方法,就可以借用:

const objA = { x: 10 };
const objB = {x: 5,getX() {return this.x;}
};console.log(objB.getX());          // 5
console.log(objB.getX.call(objA)); // 10

这里用 call(objA)getX 中的 this 强制指向 objA,就实现了“方法借用”。


3. 传递可变参数(数组转展开)

如果要把一个数组作为参数列表传给函数,用 apply 更方便:

function sum(a, b, c) {return a + b + c;
}const nums = [1, 2, 3];
console.log(sum.apply(null, nums)); // 6

等价于:

console.log(sum.call(null, nums[0], nums[1], nums[2])); // 6

在 ES6 之前,这个技巧常用于 Math.max/Math.min 获取数组最大最小值:

const arr = [5, 1, 8, 3];
const max = Math.max.apply(null, arr); // 8
const min = Math.min.apply(null, arr); // 1

ES6+ 可直接写 Math.max(...arr),但在老环境或动态参数场景下,.apply 仍然有效。


4. 构造可重用的“类”或混入(Mixin)

当多个对象需要共享同一组方法时,可以用 call/apply 在初始化时添加属性:

function Person(name) {this.name = name;
}
Person.prototype.say = function () {console.log(`Hi, I'm ${this.name}`);
};function Employee(name, company) {Person.call(this, name);  // “继承” Person 构造函数this.company = company;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;Employee.prototype.getCompany = function () {console.log(this.company);
};const emp = new Employee('Alice', 'Acme Inc.');
emp.say();        // Hi, I'm Alice
emp.getCompany(); // Acme Inc.

这里 Person.call(this, name)Employee 构造函数复用了 Person 的初始化逻辑。


5. 在事件处理或异步场景中绑定上下文

在回调函数中,this 往往丢失。可用 callapply 手动指定:

const obj = {value: 42,getValueAfterDelay(delay) {setTimeout(function () {// 普通函数中 this 指向全局或 undefinedconsole.log(this.value);  }.call(this), delay);}
};obj.getValueAfterDelay(1000);
// 42

不过更常用的是 .bind(this),它会返回一个新的函数:

setTimeout(function () {console.log(this.value);
}.bind(obj), 1000);

6. 小结

  • 何时用 .call()
    需要显式地将若干个独立参数逐一传入,并指定 this

  • 何时用 .apply()
    参数已经以数组或类数组形式准备好,想“一次性”传递给函数。

  • .bind() 的关系

    • call/apply 立即执行函数并指定 this
    • bind 返回一个新函数,后续调用时 this 永久绑定。

掌握了这三种方法,就可以灵活地控制函数执行的上下文,以及参数的传递方式,特别是在函数复用、混入、事件回调、动态参数等场景中非常有用。

相关文章:

  • Qt中的智能指针
  • 【深度学习新浪潮】以图搜地点是如何实现的?(含大模型方案)
  • 哈尔滨云前沿服务器托管,服务器租用
  • 打板策略实战对比,khQuant回测横评第三弹【AI量化第29篇】
  • 题目 3313: 蓝桥杯2025年第十六届省赛真题-电池分组
  • 云效流水线Flow使用记录
  • 宝塔安装easyswoole框架
  • 思澈科技助力Keep Watch Pilot 1:重新定义智能运动手表体验
  • 精益数据分析(88/126):从营收平衡到规模化扩张——企业增长的最后一道关卡
  • WPF中的图标闪烁功能
  • OpenAI O3惊现算法的自由意识,AGI初现?
  • 【PhysUnits】14 二进制数的标准化表示(standardization.rs)
  • 封装索引列表
  • 四、web安全-行业术语
  • 汽车电子/电气(E/E)架构将朝着区域(分区)式架构方向发展
  • Mac redis下载和安装
  • JavaEE初阶-网络编程
  • javaEE1
  • 从大模型加载到交互:3D Web轻量化引擎HOOPS Communicator如何打造流畅3D体验?
  • Django ToDoWeb 服务
  • 做网站都是需要什么/企业qq下载
  • 点击运行显示网站正在建设/2021小学生新闻摘抄
  • 没有网站如何做天天联盟/百度的人工客服电话
  • 智能网站建设软件/东莞网站公司哪家好
  • 鼓楼公司网站建设费用/网站优化推广
  • 免费推广网站大全黄色/创建自己的网址