JavaScript中call与apply方法的区别及使用

宋时安
宋时安
发布时间:2026-10-14 | 3人浏览过
原创

JavaScript中的call和apply方法主要用于改变函数执行时的this指向。两者核心功能一致,主要区别在于参数传递方式:call接受逗号分隔的参数列表,而apply必须接收一个参数数组。掌握这两个方法是理解JS面向对象编程和实现原型链继承的关键。

方法定义与核心区别

call方法:调用一个对象的一个方法,以另一个对象替换当前对象。其语法为:fun.call(thisArg[, arg1[, arg2[, ...]]])。如果没有提供thisObj参数,那么Global对象被用作thisObj。

apply方法:应用某一对象的一个方法,用另一个对象替换当前对象。其语法为:fun.apply(thisArg[, argArray])。其中argArray必须是一个有效的数组或arguments对象,否则会抛出TypeError。同样,若未提供参数,Global对象将作为默认上下文。

两者的本质作用相同,都是强行改变函数内部的this指向。主要区别在于第二个参数的形式:call支持任意数量的独立参数,而apply仅支持单个数组(或类数组对象)作为参数集合。

常见应用场景

第1步:借用其他对象的方法

当需要在一个对象上调用另一个对象的方法,且该方法依赖于调用者的上下文时,可以使用call或apply。例如,让Cat对象使用Animal的showName方法:

function Animal(){ 
 this.name = "Animal"; 
 this.showName = function(){ 
  console.log(this.name); 
 } 
} 

function Cat(){ 
 this.name = "Cat"; 
} 

var animal = new Animal(); 
var cat = new Cat(); 

// 使用call执行,this指向cat
animal.showName.call(cat); 
// 输出: Cat

// 使用apply执行,效果相同
animal.showName.apply(cat); 
// 输出: Cat

在此例中,虽然cat本身没有showName方法,但通过call/apply,我们将animal的方法“借”给cat执行,此时方法内的this指向了cat实例。

第2步:实现构造函数继承

利用call可以在子类构造函数中调用父类构造函数,从而继承父类的属性。这是一种常见的伪继承模式:

function Animal(name){ 
 this.name = name; 
 this.showName = function(){ 
  console.log(this.name); 
 } 
} 

function Cat(name){ 
 // 借用Animal构造函数,this指向Cat实例
 Animal.call(this, name); 
} 

var cat = new Cat("Black Cat"); 
cat.showName(); 
// 输出: Black Cat

这里Animal.call(this, name)等价于在Cat的作用域中执行了Animal构造函数,使得Cat实例拥有了Animal的属性和方法。

第3步:多重继承模拟

JavaScript不支持多重继承,但可以通过多次调用call来合并多个构造函数的属性:

function Class10() {
 this.showSub = function(a,b) { console.log(a-b); } 
}

function Class11() {
 this.showAdd = function(a,b) { console.log(a+b); } 
}

function Class2() {
 Class10.call(this);
 Class11.call(this);
}

var obj = new Class2();
obj.showAdd(1, 2); // 输出: 3
obj.showSub(5, 2); // 输出: 3

通过依次调用Class10.call(this)和Class11.call(this),Class2的实例同时拥有了两个类的方法和属性。

第4步:处理参数差异(数组 vs 列表)

这是call和apply最显著的操作性区别。当需要将一个数组作为参数传递给一个函数时,apply更为方便;而如果需要明确指定每个参数,call则更直观。

var Obj1 = {
 name: 'Object1',
 say: function(p1, p2) {
  console.log(this.name + ' says ' + p1 + ' ' + p2);
 }
};

var Obj2 = {
 name: 'Object2'
};

// 常规调用
Obj1.say('Good', 'morning');

// 使用call,参数逐个传递
Obj1.say.call(Obj2, 'Good', 'afternoon');

// 使用apply,参数以数组形式传递
Obj1.say.apply(Obj2, ['Good', 'afternoon again']);

注意:arguments对象是类数组对象,通常用于apply的参数传递,因为call无法直接接受arguments对象作为整体参数包(除非展开)。

总结

call和apply是JavaScript中用于改变函数上下文(this绑定)的核心工具。call适用于参数明确且数量固定的场景,apply则更适合处理动态数组参数或类数组对象(如arguments)。在实际开发中,它们常用于实现方法复用、构造函数继承以及高阶函数中的上下文管理。以上就是JavaScript中call方法和apply方法使用对比的详细内容,更多关于JavaScript基础教程的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表