Js中call和apply的区别和用法是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Js中call和apply的区别和用法是啥?相关的知识,希望对你有一定的参考价值。

参考技术A javascript中有一个call和apply方法,其作用基本相同,但也有略微的区别。\\x0d\\x0a先来看看JS手册中对call的解释:\\x0d\\x0acall 方法\\x0d\\x0a 调用一个对象的一个方法,以另一个对象替换当前对象。\\x0d\\x0acall([thisObj[,arg1[, arg2[, [,.argN]]]]])\\x0d\\x0a参数\\x0d\\x0athisObj\\x0d\\x0a可选项。将被用作当前对象的对象。\\x0d\\x0aarg1, arg2, , argN\\x0d\\x0a可选项。将被传递方法参数序列。\\x0d\\x0a说明\\x0d\\x0acall 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。\\x0d\\x0a 如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。\\x0d\\x0a \\x0d\\x0a说明白一点其实就是更改对象的内部指针,即改变对象的this指向的内容。这在面向对象的js编程过程中有时是很有用的。\\x0d\\x0a\\x0d\\x0a\\x0d\\x0acall函数和apply方法的第一个参数都是要传入给当前对象的对象,及函数内部的this。后面的参数都是传递给当前对象的参数。\\x0d\\x0a 运行如下代码:\\x0d\\x0a\\x0d\\x0a可见分别弹出了func和var。到这里就对call的每个参数的意义有所了解了。\\x0d\\x0a\\x0d\\x0a 对于apply和call两者在作用上是相同的,但两者在参数上有区别的。\\x0d\\x0a对于第一个参数意义都一样,但对第二个参数:\\x0d\\x0aapply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。\\x0d\\x0a 如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])\\x0d\\x0a\\x0d\\x0a同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入

js call apply 用法区别

来自:https://www.cnblogs.com/wdlhao/p/5614522.html

1、关于call()和apply()的疑点:

  • apply和call的区别在哪里
  • 什么情况下用apply,什么情况下用call
  • apply的其他巧妙用法(一般在什么情况下可以使用apply)

2、语法和参数分析:

apply和call都能继承另外一个对象的方法和属性;
Function.apply(obj,args)方法能接收两个参数
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args-->arguments)

call:和apply的意思一样,只不过是参数列表不一样.
Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表

3、call()和apply()示例展示:

/*定义一个Person类*/ 
function Person(name,age) { 
     this.name=name; 
     this.age=age;
} 
 /*定义一个学生类*/ 
 function Student(name,age,grade) { 
    //Person.apply(this,arguments);//特点:this指代student对象,只接收2个参数,arguments为隐式类数组对象,用来接收传入的参数;
      Person.call(this,name,age);//特点:this指代student对象,可以接收任意多个参数
      this.grade=grade; 
 } 
 var student =new Student("zhangsan",22,"二年级");//方法Student()也是object的一个实例
 //测试 
 alert("name:"+student.name+"\\n"+"age:"+student.age+"\\n"+"grade:"+student.grade);
//学生类里面我没有给name和age属性赋值啊,为什么又存在这两个属性的值呢,这个就是apply的神奇之处.

结果:

name:zhangsan
age:22
grade:"二年级"

分析: Person.apply(this,arguments);

this:在创建对象在这个时候代表的是student

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

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

4、 什么情况下用apply,什么情况下用call

使用apply的情况:在给对象参数的情况下,如果参数的形式是数组的时候,比如apply示例里面传递了参数arguments,这个参数是数组类型。

使用call的情况: 如果我的Person的参数列表是这样的(age,name),而Student的参数列表是(name,age,grade),这样就可以用call来实现了,也就是直接指定参数列表对应值的位置(Person.call(this,age,name,grade));

5、apply的一些其他巧妙用法

细心的人可能已经察觉到,在我调用apply方法的时候,第一个参数是对象(this), 第二个参数是一个数组集合, 在调用Person的时候,他需要的不是一个数组,但是为什么他给我一个数组我仍然可以将数组解析为一个一个的参数.

这个就是apply的一个巧妙的用处,可以将一个数组默认的转换为一个参数列表[param1,param2,param3] 转换为 param1,param2,param3这个如果让我们用程序来实现将数组的每一个项,来装换为参数的列表,可能都得费一会功夫,借助apply的这点特性,所以就有了以下高效率的方法:

a) Math.max 可以实现得到数组中最大的一项

因为Math.max 参数里面不支持Math.max([param1,param2]) 也就是数组

但是它支持Math.max(param1,param2,param3…),所以可以根据刚才apply的那个特点来解决 var max=Math.max.apply(null,array),这样轻易的可以得到一个数组中最大的一项(apply会将一个数组装换为一个参数接一个参数的传递给方法)

         这块在调用的时候第一个参数给了一个null,这个是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行,.所以直接传递了一个null过去

b) Math.min  可以实现得到数组中最小的一项

同样和 max是一个思想 var min=Math.min.apply(null,array);

c) Array.prototype.push 可以实现两个数组合并

同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN) 所以同样也可以通过apply来装换一下这个数组,即:

  

6、call的其他重要用法:

语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]

说明 :

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

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

6.1、直接用A对象方法来替换B对象

function add(a,b) 
{ 
alert(a+b); 
} 
function sub(a,b) 
{ 
alert(a-b); 
} 
add.call(sub,3,1); 

  分析:这个例子中的意思就是用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4); // 注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。

  6.2、直接用B对象来执行A对象的方法

function Class1() 
{ 
this.name = "class1"; 
this.showNam = function() 
{ 
alert(this.name); 
} 
} 
function Class2() 
{ 
this.name = "class2"; 
} 
var c1 = new Class1(); 
var c2 = new Class2(); 
c1.showNam.call(c2); 

  分析:注意,call 的意思是把 c1 的方法放到c2上执行,原来c2是没有showNam() 方法,现在是把c1 的showNam()方法放到 c2 上来执行,所以this.name 应该是 class2,执行的结果就是 :alert("class2");可以让a对象来执行b对象的方法。

  6.3、可以用 call 来实现继承 

function Class1() 
{ 
this.showTxt = function(txt) 
{ 
alert(txt); 
} 
} 
function Class2() 
{ 
Class1.call(this); 
} 
var c2 = new Class2(); 
c2.showTxt("cc"); 

  分析:即我没有的方法或属性,通过call继承,我就拥有了你的方法和属性,可以进行相关的操作了。这样 Class2 就继承Class1了,Class1.call(this) 的 意思就是使用 Class1 对象代替this对象,那么 Class2 中不就有Class1 的所有属性和方法了吗,c2 对象就能够直接调用Class1 的方法以及属性了,执行结果就是:alert(“cc”);

以上是关于Js中call和apply的区别和用法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

js call apply 用法区别

简述JS中 appy 和 call 的详细用法

js call()和apply()方法的区别和用法详解

js中的apply与call的用法与区别

js中call和apply的区别

js中 call() ,apply(),bing()方法三者的用法和区别