JS中的phototype详解

作者:轩脉刃

1 原型法设计模式

在.Net中可以使用clone()来实现原型法

原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展。我们称B的原型为A。

2 javascript的方法可以分为三类:

a 类方法

b 对象方法

c 原型方法

例子:

  1. functionPeople(name)
  2. {
  3. this.name=name;
  4. //对象方法
  5. this.Introduce=function(){
  6. alert("My name is "+this.name);
  7. }
  8. }
  9. //类方法
  10. People.Run=function(){
  11. alert("I can run");
  12. }
  13. //原型方法
  14. People.prototype.IntroduceChinese=function(){
  15. alert("我的名字是"+this.name);
  16. }
  17.  
  18. //测试
  19.  
  20. var p1=newPeople("Windking");
  21.  
  22. p1.Introduce();
  23.  
  24. People.Run();
  25.  
  26. p1.IntroduceChinese();

运行一下 »

3 obj1.func.call(obj)方法

意思是将obj看成obj1,调用func方法

好了,下面一个一个问题解决:

prototype是什么含义?

javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。

A.prototype = new B();

理解prototype不应把它和继承混淆。A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍。A能使用B的方法和属性。这里强调的是克隆而不是继承。可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例。

先看一个实验的例子:

  1. function baseClass()
  2. {
  3. this.showMsg =function()
  4. {
  5. alert("baseClass::showMsg");
  6. }
  7. }
  8.  
  9. function extendClass()
  10. {
  11. } extendClass.prototype =new baseClass();
  12. var instance =new extendClass();
  13. instance.showMsg();// 显示baseClass::showMsg

 

运行一下 »

我们首先定义了baseClass类,然后我们要定义extentClass,但是我们打算以baseClass的一个实例为原型,来克隆的extendClass也同时包含showMsg这个对象方法。

extendClass.prototype = new baseClass()就可以阅读为:extendClass是以baseClass的一个实例为原型克隆创建的。

那么就会有一个问题,如果extendClass中本身包含有一个与baseClass的方法同名的方法会怎么样?

下面是扩展实验2:

  1. function baseClass()
  2. {
  3. this.showMsg =function()
  4. {
  5. alert("baseClass::showMsg");
  6. }
  7. }
  8.  
  9. function extendClass()
  10. {
  11. this.showMsg =function()
  12. {
  13. alert("extendClass::showMsg");
  14. }
  15. }
  16.  
  17. extendClass.prototype =new baseClass();
  18. var instance =new extendClass();
  19.  
  20. instance.showMsg();//显示extendClass::showMsg

运行一下 »

实验证明:函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去prototype中寻找函数。或者可以理解为prototype不会克隆同名函数。

 

 

那么又会有一个新的问题:

如果我想使用extendClass的一个实例instance调用baseClass的对象方法showMsg怎么办?

 

答案是可以使用call:

  1. extendClass.prototype =new baseClass();
  2. var instance =new extendClass();
  3.  
  4.  
  5. var baseinstance =new baseClass();
  6. baseinstance.showMsg.call(instance);//显示baseClass::showMsg

运行一下 »

这里的baseinstance.showMsg.call(instance);阅读为“将instance当做baseinstance来调用,调用它的对象方法showMsg”

 

好了,这里可能有人会问,为什么不用baseClass.showMsg.call(instance);

这就是对象方法和类方法的区别,我们想调用的是baseClass的对象方法

 

最后,下面这个代码如果理解清晰,那么这篇文章说的就已经理解了:

  1. <script type="text/javascript">
  2.  
  3. function baseClass()
  4. {
  5. this.showMsg =function()
  6. {
  7. alert("baseClass::showMsg");
  8. }
  9. this.baseShowMsg =function()
  10. {
  11. alert("baseClass::baseShowMsg");
  12. }
  13. }
  14. baseClass.showMsg =function()
  15. {
  16. alert("baseClass::showMsg static");
  17. }
  18.  
  19. function extendClass()
  20. {
  21. this.showMsg =function()
  22. {
  23. alert("extendClass::showMsg");
  24. }
  25. }
  26. extendClass.showMsg =function()
  27. {
  28. alert("extendClass::showMsg static")
  29. }
  30.  
  31. extendClass.prototype =new baseClass();
  32. var instance =new extendClass();
  33.  
  34. instance.showMsg();//显示extendClass::showMsg
  35. instance.baseShowMsg();//显示baseClass::baseShowMsg
  36. instance.showMsg();//显示extendClass::showMsg
  37.  
  38. baseClass.showMsg.call(instance);//显示baseClass::showMsg static
  39.  
  40. var baseinstance =new baseClass();
  41. baseinstance.showMsg.call(instance);//显示baseClass::showMsg
  42.  
  43. </script>

 

 

 

运行一下 »

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值