JS中的prototype
<div id="cnblogs_post_body"><p>JS中的phototype是JS中比较难理解的一个部分</p> <p> </p> <p>本文基于下面几个知识点:</p> <p> </p> <p><span style="font-size: 14pt;">1 原型法设计模式</span></p> <p>在.Net中可以使用clone()来实现原型法</p> <p>原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展。我们称B的原型为A。</p> <p> </p> <p><span style="font-size: 14pt;">2 javascript的方法可以分为三类:</span></p> <p>a 类方法</p> <p>b 对象方法</p> <p>c 原型方法</p> <p>例子:</p> <div class="cnblogs_Highlighter"> <div class="cnblogs_Highlighter"> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <div><span style="color: #0000ff;">function</span><span style="color: #000000;"> People(name)<br>{<br></span><span style="color: #0000ff;"> this</span><span style="color: #000000;">.name</span><span style="color: #000000;">=</span><span style="color: #000000;">name;<br></span><span style="color: #008000;"> //</span><span style="color: #008000;">对象方法</span><span style="color: #008000;"><br></span><span style="color: #0000ff;"> this</span><span style="color: #000000;">.Introduce</span><span style="color: #000000;">=</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br> alert(</span><span style="color: #000000;">"</span><span style="color: #000000;">My name is </span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.name);<br> }<br>}<br></span><span style="color: #008000;">//</span><span style="color: #008000;">类方法</span><span style="color: #008000;"><br></span><span style="color: #000000;">People.Run</span><span style="color: #000000;">=</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br> alert(</span><span style="color: #000000;">"</span><span style="color: #000000;">I can run</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>}<br></span><span style="color: #008000;">//</span><span style="color: #008000;">原型方法</span><span style="color: #008000;"><br></span><span style="color: #000000;">People.prototype.IntroduceChinese</span><span style="color: #000000;">=</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br> alert(</span><span style="color: #000000;">"</span><span style="color: #000000;">我的名字是</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.name);<br>}<br><br> <br><br></span><span style="color: #008000;">//</span><span style="color: #008000;">测试</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br></span><span style="color: #0000ff;">var</span><span style="color: #000000;"> p1</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;"> People(</span><span style="color: #000000;">"</span><span style="color: #000000;">Windking</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br><br>p1.Introduce();<br><br>People.Run();<br><br>p1.IntroduceChinese(); <br></span></div> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p> </p> <p><span style="font-size: 14pt;">3 obj1.func.call(obj)方法 </span></p> <p>意思是将obj看成obj1,调用func方法 </p> <p> </p> <p> </p> <p>好了,下面一个一个问题解决: </p> <p> </p> <p><span style="font-size: 14pt;">prototype是什么含义? </span></p> <p> </p> <p>javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。 </p> <p>A.prototype = new B(); </p> <p>理解prototype不应把它和继承混淆。A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍。A能使用B的方法和属性。这里强调的是克隆而不是继承。可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例。 </p> <p> </p> <p>先看一个实验的例子: </p> <br> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <div><span style="color: #0000ff;">function</span><span style="color: #000000;"> baseClass()<br>{<br></span><span style="color: #0000ff;"> this</span><span style="color: #000000;">.showMsg </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">function</span><span style="color: #000000;">()<br> {<br> alert(</span><span style="color: #000000;">"</span><span style="color: #000000;">baseClass::showMsg</span><span style="color: #000000;">"</span><span style="color: #000000;">); <br> }<br>}<br><br></span><span style="color: #0000ff;">function</span><span style="color: #000000;"> extendClass()<br>{<br>}<br><br>extendClass.prototype </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> baseClass();<br>var instance </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> extendClass();<br>instance.showMsg(); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 显示baseClass::showMsg</span></div> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> </div> <p>我们首先定义了baseClass类,然后我们要定义extentClass,但是我们打算以baseClass的一个实例为原型,来克隆的extendClass也同时包含showMsg这个对象方法。</p> <p>extendClass.prototype = new baseClass()就可以阅读为:extendClass是以baseClass的一个实例为原型克隆创建的。</p> <p> </p> <p>那么就会有一个问题,<span style="font-size: 14pt;">如果extendClass中本身包含有一个与baseClass的方法同名的方法会怎么样?</span></p> <p>下面是扩展实验2:</p> <br> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <div><span style="color: #0000ff;">function</span><span style="color: #000000;"> baseClass()<br>{<br> </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.showMsg </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">function</span><span style="color: #000000;">()<br> {<br> alert(</span><span style="color: #000000;">"</span><span style="color: #000000;">baseClass::showMsg</span><span style="color: #000000;">"</span><span style="color: #000000;">); <br> }<br>}<br><br></span><span style="color: #0000ff;">function</span><span style="color: #000000;"> extendClass()<br>{<br> </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.showMsg </span><span style="color: #000000;">=</span><span style="color: #0000ff;">function</span><span style="color: #000000;"> ()<br> {<br> alert(</span><span style="color: #000000;">"</span><span style="color: #000000;">extendClass::showMsg</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br> }<br>}<br><br>extendClass.prototype </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> baseClass();<br>var instance </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> extendClass();<br><br>instance.showMsg();</span><span style="color: #008000;">//</span><span style="color: #008000;">显示extendClass::showMsg</span></div> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p> </p> <p>实验证明:函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去prototype中寻找函数。或者可以理解为prototype不会克隆同名函数。</p> <p> </p> <p>那么又会有一个新的问题:</p> <p><span style="font-size: 14pt;">如果我想使用extendClass的一个实例instance调用baseClass的对象方法showMsg怎么办?</span></p> <p> </p> <p>答案是可以使用call: </p> <br> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <div><span style="color: #000000;">extendClass.prototype </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> baseClass();<br>var instance </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> extendClass();<br><br><br></span><span style="color: #0000ff;">var</span><span style="color: #000000;"> baseinstance </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> baseClass();<br>baseinstance.showMsg.call(instance);</span><span style="color: #008000;">//</span><span style="color: #008000;">显示baseClass::showMsg</span></div> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p> </p> <p>这里的baseinstance.showMsg.call(instance);阅读为“将instance当做baseinstance来调用,调用它的对象方法showMsg”</p> <p>好了,这里可能有人会问,为什么不用baseClass.showMsg.call(instance);</p> <p>这就是对象方法和类方法的区别,我们想调用的是baseClass的对象方法</p> <p> </p> <p><span style="font-size: 14pt;">最后,下面这个代码如果理解清晰,那么这篇文章说的就已经理解了:</span></p> <p> </p> <br> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <div><span style="color: #000000;"><</span><span style="color: #000000;">script type</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">text/javascript</span><span style="color: #000000;">"</span><span style="color: #000000;">></span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">function</span><span style="color: #000000;"> baseClass()<br>{<br> </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.showMsg </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">function</span><span style="color: #000000;">()<br> {<br> alert(</span><span style="color: #000000;">"</span><span style="color: #000000;">baseClass::showMsg</span><span style="color: #000000;">"</span><span style="color: #000000;">); <br> }<br> <br> </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.baseShowMsg </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">function</span><span style="color: #000000;">()<br> {<br> alert(</span><span style="color: #000000;">"</span><span style="color: #000000;">baseClass::baseShowMsg</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br> }<br>}<br>baseClass.showMsg </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">function</span><span style="color: #000000;">()<br>{<br> alert(</span><span style="color: #000000;">"</span><span style="color: #000000;">baseClass::showMsg static</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>}<br><br></span><span style="color: #0000ff;">function</span><span style="color: #000000;"> extendClass()<br>{<br> </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.showMsg </span><span style="color: #000000;">=</span><span style="color: #0000ff;">function</span><span style="color: #000000;"> ()<br> {<br> alert(</span><span style="color: #000000;">"</span><span style="color: #000000;">extendClass::showMsg</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br> }<br>}<br>extendClass.showMsg </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">function</span><span style="color: #000000;">()<br>{<br> alert(</span><span style="color: #000000;">"</span><span style="color: #000000;">extendClass::showMsg static</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br>}<br><br>extendClass.prototype </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> baseClass();<br>var instance </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> extendClass();<br><br>instance.showMsg(); </span><span style="color: #008000;">//</span><span style="color: #008000;">显示extendClass::showMsg</span><span style="color: #008000;"><br></span><span style="color: #000000;">instance.baseShowMsg(); </span><span style="color: #008000;">//</span><span style="color: #008000;">显示baseClass::baseShowMsg</span><span style="color: #008000;"><br></span><span style="color: #000000;">instance.showMsg(); </span><span style="color: #008000;">//</span><span style="color: #008000;">显示extendClass::showMsg</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>baseClass.showMsg.call(instance);</span><span style="color: #008000;">//</span><span style="color: #008000;">显示baseClass::showMsg static</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br></span><span style="color: #0000ff;">var</span><span style="color: #000000;"> baseinstance </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> baseClass();<br>baseinstance.showMsg.call(instance);</span><span style="color: #008000;">//</span><span style="color: #008000;">显示baseClass::showMsg</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br></span><span style="color: #000000;"><</span><span style="color: #000000;">/</span><span style="color: #000000;">script></span></div> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p> </p> <p>作者:轩脉刃(yjf512)<br>出处:(<a href="http://www.cnblogs.com/yjf512/">http://www.cnblogs.com/yjf512/</a>)<br>版权声明:本文的版权归作者与博客园共有。欢迎转载阅读,转载时须注明本文的详细链接。 </p> <p> </p> <p>[参考文章]</p> <p><a title="http://tech.ddvip.com/2009-05/1243588303121461.html" href="http://tech.ddvip.com/2009-05/1243588303121461.html">http://tech.ddvip.com/2009-05/1243588303121461.html</a></p> <p><a title="http://jetway.iteye.com/blog/56533" href="http://jetway.iteye.com/blog/56533">http://jetway.iteye.com/blog/56533</a></p> <p><a title="http://xiaofeizm55333.iteye.com/blog/80913" href="http://xiaofeizm55333.iteye.com/blog/80913">http://xiaofeizm55333.iteye.com/blog/80913</a></p> <p> </p> <p> </p> </div></div>