【javascript】javascript中call及apply函数作用:主要实现将函数绑定到另外一个对象上去运行

call和apply,它们的作用都是将函数绑定到另外一个对象上去运行 
两者的格式和参数定义: 
call( thisArg [,arg1,arg2,… ] );       // 参数列表,arg1,arg2,... 
apply(thisArg [,argArray] );                 // 参数数组,argArray 
上面两个函数内部的this指针,都会被赋值为thisArg,这可实现将函数作为另外一个对象的方法运行的目的 

一、call 的简单用法 
首先,我们先看个简单的例子(call): 
Html代码   收藏代码
  1. <!doctype html>  
  2. <html>  
  3.     <head>  
  4.         <title> call-apply </title>  
  5.     </head>  
  6.   
  7.     <body>  
  8.         <input type="text" id="idTxt" value="input text">  
  9.           
  10.         <script type="text/javascript">  
  11.             var value = "global var";  
  12.               
  13.             function mFunc()  
  14.             {  
  15.                 this.value = "member var";  
  16.             }  
  17.               
  18.             function gFunc()  
  19.             {  
  20.                 alert(this.value);  
  21.             }         
  22.                                                       
  23.             window.gFunc();                                 // show gFunc, global var  
  24.             gFunc.call(window);                             // show gFunc, global var  
  25.             gFunc.call(new mFunc());                        // show mFunc, member var  
  26.             gFunc.call(document.getElementById('idTxt'));   // show element, input text  
  27.         </script>  
  28.           
  29.         <script language="javascript">  
  30.             var func = new function()  
  31.             {  
  32.                 this.a = "func";  
  33.             }  
  34.               
  35.             var func2 = function(x)  
  36.             {  
  37.                 var a = "func2";  
  38.                 alert(this.a);                
  39.                 alert(x);  
  40.             }  
  41.               
  42.             func2.call(func, "func2");                      // show func and func2  
  43.         </script>  
  44.     </body>  
  45. </html>  

然后,运行结果如下: 
global var 
global var 
member var 
input text 
func 
func2 
测试环境:Google Chrome 10.0.648.45 
最后,分析结果 
1、全局对象window调用函数gFunc,this指向window对象,因此this.value为global var 
2、函数gFunc调用call方法,this默认指向第一个参数window对象,因此this.value也为global var 
3、函数gFunc调用call方法,this默认指向第一个参数new mFunc(),即mFunc的对象,因此this.value为mFunc的成员变量member var 
4、函数gFunc调用call方法,this默认指向第一个参数input text控件,即id=‘idTxt’的控件,因此this.value为input控件的value值input text 
5、函数func2调用call方法,this默认指向第一个参数func函数对象,因此this.value为this.a,即func 
6、函数func2调用call方法,第二个参数属于函数对象func2的参数,因此alert(x)为第二个参数func2 

二、call 继承用法与改进 
js使用call模拟继承 
测试代码: 
Html代码   收藏代码
  1. <!doctype html>  
  2. <html>  
  3.     <head>  
  4.         <title> call - apply for inherit </title>  
  5.     </head>  
  6.       
  7.     <body>  
  8.         <script type="text/javascript">  
  9.             function baseA()        // base Class A  
  10.             {  
  11.                 this.member = "baseA member";  
  12.                 this.showSelfA = function()  
  13.                 {  
  14.                     window.alert(this.member);  
  15.                 }  
  16.             }  
  17.               
  18.             function baseB()        // base Class B  
  19.             {  
  20.                 this.member = "baseB member";  
  21.                 this.showSelfB = function()  
  22.                 {  
  23.                     window.alert(this.member);  
  24.                 }  
  25.             }  
  26.               
  27.             function extendAB()     // Inherit Class from A and B  
  28.             {  
  29.                 baseA.call(this);   // call for A  
  30.                 baseB.call(this);   // call for B  
  31.             }  
  32.               
  33.             window.onload = function()  
  34.             {  
  35.                 var extend = new extendAB();      
  36.                 extend.showSelfA();     // show A  
  37.                 extend.showSelfB();     // show B  
  38.             }  
  39.         </script>  
  40.     </body>  
  41. </html>  

运行结果如下: 
baseB member 
baseB member 
测试环境:Google Chrome 10.0.648.45 
结果分析: 
预期的结果,应该是输出 baseA member 和 baseB member,但实际输出却是 baseB member 和 baseB member
(已在IE9、8、6,Maxthon、Chrome、FF、Opera、Safari、360等浏览器测试过,结果都是后者:baseB member) 
至此,机器是不会错的,这就需要我们深入分析 
我们可能会很容易想到是this引起的,this两次都指向了baseB对象,但是推测真是这样吗? 
为了探究实质,我们借助chrome浏览器的调试工具,下断点,进行调试,结果发现: 

当调用extend.showSelfA();时,此时的this指向extendAB(并不是我们推测的两次都指向baseB对象) 
真实原因是extendAB对象的成员变量member在被baseB.call(this);实例化时,被baseB的成员member覆盖了,即extendAB的成员member由baseA member赋值成了baseB member 
当然,我们也可以对上面baseA代码稍作修改,来验证我们调试分析的正确性: 
Js代码   收藏代码
  1. function baseA()        // base Class A  
  2. {  
  3.     this.memberA = "baseA member";   // member改成memberA,以区分baseB中的member  
  4.     this.showSelfA = function()  
  5.     {  
  6.         window.alert(this.memberA);    // 显示memberA  
  7.     }  
  8. }  

再次运行chrome等浏览器,结果如下: 
baseA  member 
baseB member 
结果和我们的预期相同,同时chrome调试信息也验证了我们的正确性: 



继承改进(prototype) 
以上模拟继承方法,仔细分析不是最好的。 
因为每次在函数(类)中定义了成员方法,都会导致实例有副本,因此可以借助prototype原型,进行改进 
改进举例如下: 
<!doctype html> 

<html> 
<head> 
<title> call - apply for prototype </title> 
</head> 

<body> 
<script type="text/javascript"> 
var Class = { 
create: function() // create Function 

return function() 

this.initialize.apply(this, arguments); 


}; 

var Person = Class.create(); // Create Class Person 
Person.prototype = { // prototype initialize 
initialize: function(obj1, obj2) 

this.obj1 = obj1; 
this.obj2 = obj2; 
}, 
showSelf: function() 

alert("obj: " + this.obj1 + " and " + this.obj2); 



// instance Class 
var person = new Person("man", "women"); // two params 
person.showSelf(); // show person 
</script> 
</body> 
</html> 
运行结果如下: 
obj: man and women

你可能感兴趣的:(【javascript】javascript中call及apply函数作用:主要实现将函数绑定到另外一个对象上去运行)