如何理解JS中的call和apply?

本文介绍了JavaScript中call和apply方法的用途,它们都用于改变函数执行时的上下文,即this的指向。文章详细阐述了apply的用法,包括其接收的两个参数,以及call与apply的区别。通过示例代码展示了如何使用这两种方法,并解释了它们在参数传递上的差异。同时,文章还提到了call在执行效率上的微小优势。最后,通过比较call和apply在处理参数的不同方式,给出了适用场景的建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里是修真院前端小课堂,每篇分享文从

【如何理解JS中的call和apply? 】

1.背景介绍
call和apply都是为了改变某个函数运行时的context即上下文而存在的,换句话说,就是为了改变函数体内部this的指向。因为JavaScript的函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。

2.知识剖析
2.1 apply:

方法能劫持另外一个对象的方法,继承另外一个对象的属性.

Function.apply(obj,args)方法能接收两个参数

obj:这个对象将代替Function类里this对象

args:这个是数组,它将作为参数传给Function(args–>arguments)

2.2 call

和apply的意思一样,只不过是参数列表不一样

Function.call(obj,[param1[,param2[,…[,paramN]]]])

obj:这个对象将代替Function类里this对象

params:这个是一个参数列表

3.常见问题
如何使用call和apply?

4.解决方案
call和apply的作用基本类似, 都是去执行function并将这个function的context替换成第一个参数带入。

两者的不同是call必须将function的参数一一带入,而apply只要在第二个参数带入一个数列。

function fn( arg1, arg2,… ){
// do something
}
fn( arg1, arg2,… );
fn.call( context, arg1, arg2,… );
fn.apply( context, [ arg1, arg2,… ]);
call方法

调用一个对象的一个方法,以另一个对象替换当前对象。

call([thisObj[,arg1[, arg2[, [,.argN]]]]])

参数

thisObj

可选项。将被用作当前对象的对象。

arg1, arg2, , argN

可选项。将被传递方法参数序列。

说明

call方法可以用来代替另一个对象调用一个方法。call方法可将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象。

如果没有提供thisObj参数,那么Global对象被用作thisObj。

var func=new function(){this.a=“func”}
var newfunc=function(x){
var a=“newfunc”;
alert(this.a);
alert(x);
}
newfunc.call(func,“inputParameter1”);
/*alert are

  • func/inputParameter1; not newfunc/inputParameter1
    */
    从以上的例子可以看出,alert(this.a),返回的是并不是当前函数里的值。

使用call执行的速度会稍微快一些, 不过差异不大。

demo1:

/定义一个人类/
function Person(name,age)
{
this.name=name;
this.age=age;
}
/定义一个学生类/
function Student(name,age,grade)
{
Person.apply(this,arguments);
//Person.call(this,name,age);
this.grade=grade;
}
//创建一个学生类
var student=new Student(“zhangsan”,21,“一年级”);
//测试
alert(“name:”+student.name+"\n"+“age:”+student.age+"\n"+“grade:”+student.grade);
//大家可以看到测试结果name:zhangsan age:21 grade:一年级
//学生类里面我没有给name和age属性赋值啊,为什么又存在这两个属性的值呢,这个就是apply的神奇之处.
Person.apply(this,arguments);
this:在创建对象在这个时候代表的是student;

arguments:是一个数组,也就是[“zhangsan”,”21”,”一年级”];

也就是通俗一点讲就是:用student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面

demo2

function Animal(){
this.name = “Animal”;
this.showName = function(){
alert(this.name);
}
}
function Cat(){
this.name = “Cat”;
}
var animal = new Animal();
var cat = new Cat();
//通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。
//输入结果为"Cat"
animal.showName.call(cat,",");
//animal.showName.apply(cat,[]);
call的意思是把animal的方法放到cat上执行,原来cat是没有showName()方法,现在是把animal的showName()方法放到cat上来执行,所以this.name应该是Cat

5.编码实战
6.扩展思考
call()和apply()两种方法的区别?

相同点:两个方法产生的作用是完全一样的

不同点:方法传递的参数不同

call()接受的是一个参数列表,而apply()接受一个参数数组。

func.call(this, arg1, arg2);

func.apply(this, [arg1, arg2])

其中this是你想指定的上下文,他可以是任何一个JavaScript对象(JavaScript中一切皆对象),call需要把参数按顺序传递进去,而apply则是把参数放在数组里。因此要说适用条件的话,当你的参数是明确知道数量时用call。 而不确定的时候用apply,然后把参数push进数组传递进去。

举个小栗子来区别call和apply

获取数组中的最大值和最小值

var numbers = [5, 458 , 120 , -215 ];
Math.max.apply(Math, numbers);
Math.max.call(Math,5, 458 , 120 , -215);
7.参考文献
参考一:js中bind、call、apply函数的用法

参考二:Js apply方法 详解

参考三:Javascript中call,apply,bind方法的详解与总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值