JS中 call和apply的区别和作用

Posted

tags:

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

参考技术A javascript中的每一个function对象都会有call和apply方法
定义:
apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。

call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法

从定义中可以看出,call和apply都是调用一个对象的一个方法,用另一个对象替换当前对象。而不同之处在于传递的参数,apply最多只能有两个参数——新this对象和一个数组argArray,如果arg不是数组则会报错TypeError;
call则可以传递多个参数,第一个参数和apply一样,是用来替换的对象,后边是参数列表。
参考技术B Javascript的每个Function对象中有一个apply方法:
function.apply([thisObj[,argArray]])
还有一个类似功能的call方法:
function.call([thisObj[,arg1[, arg2[, [,.argN]]]]])
它们各自的定义:
apply:应用某一对象的一个方法,用另一个对象替换当前对象。
call:调用一个对象的一个方法,以另一个对象替换当前对象。
它们的共同之处:
都“可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。”
它们的不同之处:
apply:
最多只能有两个参数——新this对象和一个数组 argArray。如果给该方法传递多个参数,则把参数都写进这个数组里面,当然,即使只有一个参数,也要写进数组里面。如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj,并且无法被传递任何参数。
call:
则是直接的参数列表,主要用在js对象各方法互相调用的时候,使当前this实例指针保持一致,或在特殊情况下需要改变this指针。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
更简单地说,apply和call功能一样,只是传入的参数列表形式不同:如 func.call(func1,var1,var2,var3) 对应的apply写法为:func.apply(func1,[var1,var2,var3])
也就是说:call调用的为单个,apply调用的参数为数组
function sum(a,b)
console.log(this === window);//true
console.log(a + b);

sum(1,2);
sum.call(null,1,2);
sum.apply(null,[1,2]);
作用  
a、调用函数
var info = 'tom';
function foo()
//this指向window
var info = 'jerry';
console.log(this.info); //tom
console.log(this===window) //true

foo();
foo.call();
foo.apply();
b、call和apply可以改变函数中this的指向  
var obj =
info:'spike'
;
foo.call(obj); //这里foo函数里面的this就指向了obj
foo.apply(obj);
c、借用别的对象的方法
求数组中的最大值
var arr = [123,34,5,23,3434,23];
//方法一
var arr1 = arr.sort(function(a,b)
return b-a;
);
console.log(arr1[0]);
//方法二
var max = Math.max.apply(null,arr) //借用别的对象的方法
console.log(max);

Javascript中call和apply的区别与详解

在js中call和apply它们的作用是改变函数调用对象,实现继承

例如:

改变调用对象

function a(x,y)
{
    alert(x+y);
}
function b(x,y)
{
    alert(x-y);
}
a.call(b,1,5) //将a方法交给b用,结果为5

 改变this指向

function b()
{
    alert(this)
}
b(); //window
b.call(); //window
b.call(“a”,2,3); //a
方法b定义时属于全局对象window,当b.call("a")时,方法b有=由对象“a”调用
 var a = function () {  
  alert(this.name);  
};  
 var b = {  
  name: "xiaohua"  
};  
a.call(b)  //带有nmae属性的对象b调用方法a,a方法中的this指向b

  

实现继承

function Animal(name)
{
    this.name=name;
    this.showName=function()
  {
      alert(this.name)
  }
}
function Cat(name) { Animal.call(this,name); //将Animal应用到Cat上,因此Cat拥有了Animal的所有属性和方法 }
var cat = new Cat(“Black Cat”); cat.showName(); //浏览器弹出Black Cat

  

apply和call的用法相同,只有传参方式不同

a.call(b,arg1,arg2…) // 方法.call(对象,参数,参数。。。。)

a.apply(b,[arg1,arg2]) // 方法.apply(对象,[参数,参数。。。。])

 

apply的一些其他巧妙用法

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

       因为Math.max不支持Math.max([param1,param2])也就是数组,但是它支持Math.max(param1,param2...),所以可以根据apply的特点来解决 var max=Math.max.apply(null,array),这样就轻易的可以得到一个数组中的最大项(apply会将一个数组转换为一个参数接一个参数的方式传递给方法)
这块在调用的时候第一个参数给了null,这是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行,所以直接传递了一个null过去。
用这种方法也可以实现得到数组中的最小项:Math.min.apply(null,array)
 
(2)Array.prototype.push可以实现两个数组的合并
        同样push方法没有提供push一个数组,但是它提供了push(param1,param2...paramN),同样也可以用apply来转换一下这个数组,即:
     1.var arr1=new Array("1","2","3");
          2.var arr2=new Array("4","5","6");
          3.Array.prototype.push.apply(arr1,arr2);    
   //得到合并后数组的长度,因为push就是返回一个数组的长度也可以这样理解,arr1调用了push方法,参数是通过apply将数组转换为参数列表的集合



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

js中的call,apply,bind区别

JS call,apply, bind区别

Js(Javascript)的apply call 和bind区别

js中call和apply的区别

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

js/javascript : apply,call,bind三者的使用与区别