码迷,mamicode.com
首页 > 移动开发 > 详细

apply() 和 call()

时间:2015-04-12 14:34:45      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:

apply()和call()都是属于Function.prototype的一个方法。是JavaScript引擎内在实现的,因为属于Function.prototype,所以每个Function对象实例,也就是每个方法都有call, apply属性.既然作为方法的属性,那它们的使用就当然是针对方法的了.这两个方法是容易混淆的,因为它们的作用一样,只是使用方式不同.
 

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

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

用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。

apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.  
 
  • Function.apply(obj,args)方法能接收两个参数
  • obj:这个对象将代替Function类里this对象  
  • args:这个是数组,它将作为参数传给Function(args-->arguments)  
  • function的方法应用到obj上?
  • call, apply作用就是借用别人的方法来调用,就像调用自己的一样.
call()方法与apply()方法的作用相同,它们的区别仅在于接受参数的方式不同,它的第二个参数是一个参数列表,在使用call()时,传递的参数必须逐个列出来。 
 
apply()实例:
 1 function Person(name,age){
 2           this.name = name;
 3           this.age  age;
 4 }
 5 function Student(name,age,grade){
 6           Person.apply(this.arguments);
 7           this.grade = grade;
 8 }
 9 var student = new Student("123‘,12,"三年级");
10 alert("name:"+student.name+"age:"+student.age+"grade:"+student.grade);
11 //name:123 age:12 grade:三年级

 

 
 
分析:Person.apply(this,arguments);
this:在创建这个对象的时候代表的是student
arguments:["123‘,12,"三年级"];
换句话说就是:用student去执行Person这个类里面的内容在Person 这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面。
 
call()的实例:
Person.call(this,name,age);  
 
 
两者的选择:取决于采取哪种给函数传递参数的方式最方便。如果打算直接传入arguments对象,或者函数中先接受到的也是一个数组,那么用apply()肯定更方便,否则选择call();
 
 
一些应用:
1.Math.max:
1 var value = [1,2,3,4,5,6,7,8,9];
2 
3 var max = Math.max.apply(Math.value);

 

 
把Math对象作为apply()的第一个参数,从而正确设置this 的值,然后可以将任何数组作为第二个参数。
 
(因为Math.max 参数里面不支持Math.max([param1,param2]) 也就是数组,但是它支持Math.max(param1,param2,param3…),所以可以根据刚才apply的那个特点来解决 var max=Math.max.apply(null,array),这样轻易的可以得到一个数组中最大的一项(apply会将一个数组装换为一个参数接一个参数的传递给方法)这块在调用的时候第一个参数给了一个null,这个是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行,.所以直接传递了一个null过去 )
 
2.Array.prototype.push
同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN) 所以同样也可以通过apply来装换一下这个数组,即: 
1 var arr1 = new Array("1","2","3");
2 
3 var arr2 = new Array("4","5","6");
4 
5  
6 
7 Array.prototype.push.apply(arr1,arr2);

 

也可以这样理解,arr1调用了push方法,参数是通过apply将数组装换为参数列表的集合.
 
3.Array.prototype.slice.call(arguments)
//能将具有length属性的对象转换成数组。
(附数组转换通用函数):
 1 var toArray = function(s){
 2           try{
 3                      return Array.prototype.slice.call(s);
 4              }catch(e){
 5                                        var arr = [];
 6                                        for(var i = 0, len = s.length; i< len;i++)
 7                                                  arr[i] = s[i];(arr.push(s[i]))
 8                                        return arr;
 9                              }
10 }

 

 
apply()和call()的真正用武之地是能够扩充函数赖以运行的作用域
 1 window.color = "red";
 2 var o = {color:"blue"};
 3 
 4 function sayColor(){
 5           alert(this.color);
 6 }
 7 
 8 sayColor();//red
 9 sayColor.call(this);//red
10 sayColor.call(window);//red
11 sayColor.call(o);//blue

 

使用call()或者apply()来扩从作用域的最大好处,就是对象不需要与方法有任何耦合关系。
 
bind()这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
 1 window.color = "red";
 2 var o = {color:"blue"};
 3 
 4 function sayColor(){
 5           alert(this.color);
 6 }
 7 
 8 sayColor();//red
 9 sayColor.call(this);//red
10 sayColor.call(window);//red
11 sayColor.call(o);//blue

 

apply() 和 call()

标签:

原文地址:http://www.cnblogs.com/solomonhit/p/4419440.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!