JavaScript中apply与call方法

一、定义

  • apply:应用某一对象的一个方法,用另一个对象替换当前对象。
  • call:调用一个对象的一个方法,以另一个对象替换当前对象。

二、apply

  //apply
   function Person(name,age){
       this.name=name;
       this.age=age;

       this.getName=function(){
           console.log("姓名:"+this.name);
       }

       this.getAge=function(){
           console.log("年龄:"+this.age);
       }
   }

    function Student(name,age,grade){
        Person.apply(this,arguments);
        this.grade=grade;

        this.getGrade=function(){
            console.log("年级:"+this.grade);
        }
    }

    console.log("apply:")
    var student=new Student('gkl',20,6);
    student.getName();
    student.getAge();
    student.getGrade();

测试结果:

分析:

Person.apply(this,arguments);

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

arguments:是一个数组,也就是[“gkl”,20,6];

student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面

三、call

call方法只是参数格式不一样

 //call
    function Person1(age,name){
        this.name=name;
        this.age=age;

        this.getName=function(){
            console.log("姓名:"+this.name);
        }

        this.getAge=function(){
            console.log("年龄:"+this.age);
        }
    }

    function Student1(name,age,grade){
        Person.call(this,age,name);
        this.grade=grade;

        this.getGrade=function(){
            console.log("年级:"+this.grade);
        }
    }

    console.log("call:");
    var student1=new Student1('gkl',20,6);
    student1.getName();
    student1.getAge();
    student1.getGrade();

效果和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来转换一下这个数组,即:

var arr1=new Array("1","2","3");

var arr2=new Array("4","5","6");

Array.prototype.push.apply(arr1,arr2); 

也可以这样理解,arr1调用了push方法,参数是通过apply将数组装换为参数列表的集合。

d) 小结:通常在什么情况下,可以使用apply类似Math.min等之类的特殊用法:

一般在目标函数只需要n个参数列表,而不接收一个数组的形式([param1[,param2[,…[,paramN]]]]),可以通过apply的方式巧妙地解决这个问题。

五、异同

共同之处:

  • 都“可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。”——摘自JScript5.5 .chm

不同之处:

  • 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])

参考资料:

  (1)http://my.oschina.net/warmcafe/blog/74973

补充资料:

(1)javascript中apply方法和call方法的作用以及prototype.js中的应用

 

posted @ 2016-05-26 19:25  GKL2013  阅读(179)  评论(0编辑  收藏  举报
NEW BLOG TOP