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(); //-->