this, Function.apply 及Function.call


考虑以下这段代码:

 1      < input type = " button "  id = " btnSubmit "  value = " Click me! "   />
 2
 3      < script language = " javascript "  type = " text/javascript " >
 4          function  ButtonManager(buttonId, message)
 5          {
 6              this ._message  =  message;
 7             document.getElementById(buttonId).onclick  =   this .ShowMessage;    
 8         }

 9         
10         ButtonManager.prototype.ShowMessage = function ()
11          {
12             alert( this ._message);
13         }

14         
15          var  btnManager  =   new  ButtonManager( " btnSubmit " " Hello! " );
16      </ script >


        按预想的意图,当点击按钮时,应当会弹出"Hello!",但 上面的代码运行,却弹出"undefined"。问题出在哪里呢?在12行设个断点,对它进行调试,发现this竟然是指向btnSubmit,如果是这 样的话,那就难怪会弹出"undefined",因为btnSubmit本身并没有定义_message,而我们所期望的this应当是指向 btnManager,我们真正期望调用的方法其实是btnManager.ShowMessage()。
         
       事实上,这是与Javascript的语法和运行机制有关的,当ShowMessage真正调用前,this的指向是不明确,而只有在运行里,this的指向会由运行时来决定。

       那么有没有什么方法来正确实现上述意图呢?答案是肯定的,首先要可以看下面的代码:

1 var  x = 10 ;
2 var  o  = {x: 15 } ;
3 function  foo()
4 {
5 alert(this.x);
6 }

7 foo();
8 foo.call(o);

    运行之后,我们会发现结果会分别是10和15。这似乎有点疑惑了,当然关键点肯定就是那个Call了。
Javascript 中的function本身也是一个object,它本身就会有tostring(),call(),apply()几个附加方法。这个 function.call的意义就在于,当调用时它时,运行时会把它的第一个参数替换掉function的this指向。
      当调用foo()时,this是指向window的,而事实上,所有的全局变量就是window的属性。foo.call(o)时,this是指向o的。
理解了function.call的作用,当解决上面的问题就不难了。

 1      < input type = " button "  id = " btnSubmit "  value = " Click me! "   />
 2
 3      < script language = " javascript "  type = " text/javascript " >
 4          function  ButtonManager(buttonId, message)
 5          {
 6              this ._message  =  message;
 7             document.getElementById(buttonId).onclick  =  createDelegate( this , this .ShowMessage);
 8         }

 9         
10         ButtonManager.prototype.ShowMessage = function ()
11          {
12             alert( this ._message);
13         }

14         
15          function  createDelegate(object, method)
16          {
17              var  delegate  =   function ()
18                  {
19                     method.call(object);
20                 }

21               return  delegate;
22         }

23         
24          var  btn  =   new  ButtonManager( " btnSubmit " " Hello! " );
25
26      </ script >


我们加入一个createDelegate的funciton,它的作用类似为onclick事件创建一个事件委托对象。现在,代码可以正常工作了。

另外,function.apply()和function.call()基本功能是一样的,但apply却可以授受两个参数,而且第二个参数必须是一个数组。

 1          var  o  =   {x: 10 } ;
 2          function  f(message)
 3          {
 4             alert(message + ( this .x * this .x));
 5         }

 6         
 7          function  g(object, func)
 8          {
 9              var  args  = [];
10              for ( var  i = 2 ;i < arguments.length;i ++ )
11              {
12                 args.push(arguments[i]);
13             }

14             func.apply(object,args);
15         }

16         
17         g(o,f, " result :  " );


基于apply的这个特点,apply比call使用更加广泛,在javascript中的继承中,apply的使用也是必不可少的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值