ITPub博客

首页 > Linux操作系统 > Linux操作系统 > javacscript apply and call

javacscript apply and call

原创 Linux操作系统 作者:ForTechnology 时间:2011-08-05 17:22:40 0 删除 编辑
call方法:
语法:a.call(b,param1,param2.....paramN);
说明:a 方法,b方法,param1,param2.....paramN 为a方法的参数,参数可以有多个也可以没有,多个参数用逗号隔开。
apply方法:
语法:a.apply(b,[param1,param2....paramN])
说明:a 方法,b方法,[param1,param2.....paramN] 为a方法的参数,参数可以有多个也可以没有,必须以数组的形式。
call和apply方法相同,只不过传参数的方法不同,a、b两个方法相当于继承,a像父类,b像子类,b有a的所有方法。

    call && apply
    
    



<!--
 
function a(name,age){
    this.name=name;
    this.age=age;
    this.showName=function(){
        alert(this.name);   
    }
}
function b(dep){
    this.dep=dep;
}
var c = new b("English!!!")
//a.call(c,"black cat",19);
a.apply(c,["black cat",19]);
c.showName();
alert(c.dep);
// -->

看javascript的call 和apply的用法 收藏
本来是想在这里写写call 和apply的用法,但是我刚在网上看到一篇讨论,感觉比较讲得彻底,拿过来吧 ,自己又懒了一把,
function foo(x) {
  this.x = x;
  var y = "Just a y";
}
function bar(foo) {
 return function() {
    var temp = {};
   foo.apply(temp, arguments);
    alert("In bar now");
    alert("temp.foo:" + temp.foo + "\n" +
      "temp.x:" + temp.x + "\n" +
      "temp.y:" + temp.y);//注意看这一行的执行结果
 }
}
var func = bar(foo);
func("In foo now");
试验结果表明:apply以后,temp对象就继承了foo类的公有变量了。也就是说,这一句 foo.apply(temp, arguments);实际上就是把foo()函数当成temp对象的构造函数来调用了。一旦构造完毕,temp对象就具有了成员this.x。
这样,我有了两种理解方案:
①按照传统的面向对象的语言来理解:一般来说,构造函数是不能被外界(不包括派生类)访问的。因此,这句话“调用apply时,是把foo函数变成temp对象的方法,然后调用”是正确的,而“可是temp.foo竟然没有定义”则是理所当然的事情了。
②按照JavaScript语言自身的对象机制来理解:在JavaScript中,(构造 )函数就是国王、一等公民,它就是类就是它。对象则是(构造)函数的实例。因此,通过对象来访问构造函数,显然是行不通的。
其实,说构造未必准确(但我们可以利用构造函数来理解这个处理过程),我认为应该说成克隆,也就是说系统把foo类拥有的所有公有变量复制给了temp对象(这里是指Object,Function,Array和包装型对象“四类”对象)。
蓝色的文字表明,如果temp不是一个对象型(指以上提到的四类对象)变量的话,克隆过程就不会发生,如下所示:
foo.apply(0, arguments);
foo.apply(null, arguments);
foo.apply(undefined, arguments);
foo.apply(true, arguments);
foo.apply("hello,world", arguments);
foo.apply({}, arguments);
那么foo.apply()实际上就和普通的方法调用没有什么区别了,只是有了它,我们可以利用传递arguments参数的便利。
所以,apply(和call)的应用场合就浮现出来了:
①我们需要把一个类的公有变量复制给另一个对象。
②我们要快速而“智能”的传参,而不是手动去书写arguments[0],arguments[1]...
问一个函数与函数之间传参数的问题,我觉得我这种方法太麻烦,不知道大家还有没有更好的方法.
如果按传统的方式来,得这样写:
function  user( ) {
  test(arguments[0], arguments[1]);
}
function test(id,name) {
   alert(id +"-----------"+name);
}
user("dfdfd","kkkkk");
这样写的缺点很明显,万一参数一变,程序就挂了。
而利用apply,程序就变聪明多了:
function  user( ) {
  test.apply(0, arguments);
}
function test(id,name) {
   alert(id +"-----------"+name);
}
user("dfdfd","kkkkk");
apply(...)和call(...)确实很实用,比如实现一个类创建模式

<!--
var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
};
var vehicle = Class.create();
vehicle.prototype = {
    initialize: function(type){
        this.type=type;
    },
    showSelf: function(){
        alert("this vehicle is "+ this.type);
    }
};
var moto=new vehicle("Moto");
moto.showSelf();
//-->


一个跨框架调用的例子
在View框架中有三个测试button,点击分别对应三种调用方式,第一种是通过最原始的obj.fn()来调用Controller框架中的fn函数,第二种是比较原始的eval拼装arguments跨框架字符串,第三种是改写的apply方法应用~
/**
 * index.htm
 */




测试跨框架调用-apply()应用


 
 

<br>&nbsp; <body> UnSupport Frame. Structure! </body><br>


/**
 * view.htm
 */




:::View:::

<!--
// Cross Frames Function
var fFunc = function(){
 try{
  var iLen = arguments.length;
  if(iLen == 0) return;
  else{
   var sFuncStr = "top.frames['js_frame'].";
   sFuncStr += arguments[0] + "(";
   for(var i=1; i    sFuncStr += "'" + arguments[i] + "',";
   }
   sFuncStr = sFuncStr.substring(0, sFuncStr.length-1);
   sFuncStr += ");";
   eval(sFuncStr);
  }
 }
 catch(ex){
  window.alert("Error: " + ex.description);
 }
};
// Cross Frames Function Apply
var fGoto = function(){
 try{
  var sFuncStr = "top.frames['js_frame'].";
  var arr = [];
  for(var i=0; i   arr[i] = arguments[i];
  }
  arr = arr.slice(1);
  var func = eval(sFuncStr + arguments[0]);
  func.apply(window, arr);
 }
 catch(ex){
  window.alert("Error: " + ex.description);
 }
};
//-->









/**
 * controller.htm
 */




:::Controller:::

<!--
function fTest(sStr1, sStr2){
 window.confirm(sStr1);
 window.alert(sStr2);
}
//-->



:::JS Frame.:




提一点建议。。。利用apply的那一个函数可以优化如下:
// Cross Frames Function Apply
var fGoto = function(){
 try{ 
    var arr = [];
      for(var i=0; i       arr[i] = arguments[i];
      }
      arr = arr.slice(1);
   parent.frames['js_frame'][arguments[0]].apply(0, arr);
 }
 catch(ex){
  window.alert("Error: " + ex.description);
 }
};

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25897606/viewspace-704293/,如需转载,请注明出处,否则将追究法律责任。

下一篇: js 原型链
请登录后发表评论 登录
全部评论

注册时间:2011-07-21

  • 博文量
    220
  • 访问量
    667518