JS中的prototype[通俗易懂]

JS中的prototype[通俗易懂]JS中的phototype是JS中比较难理解的一个部分本文基于下面几个知识点:1原型法设计模式在.Net中可以使用clone()来实现原型法原型法的主要思想是,现在有1个类A,我想要创建一个类B,这

大家好,又见面了,我是你们的朋友全栈君。

JS中的phototype是JS中比较难理解的一个部分

 

本文基于下面几个知识点:

 

1 原型法设计模式

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

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

 

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

a 类方法

b 对象方法

c 原型方法

例子:

function
 People(name)
{

  this
.name
=
name;

  //
对象方法


  this
.Introduce
=
function
(){
    alert(

“
My name is 
“
+
this
.name);
  }
}

//
类方法


People.Run
=
function
(){
  alert(

“
I can run
“
);
}

//
原型方法


People.prototype.IntroduceChinese
=
function
(){
  alert(

“
我的名字是
“
+
this
.name);
}

 


//
测试




var
 p1
=
new
 People(
“
Windking
“
);

p1.Introduce();

People.Run();

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的实例。

 

先看一个实验的例子:

function
 baseClass()
{

  this
.showMsg 
=
 
function
()
  {
     alert(

“
baseClass::showMsg
“
);   
  }
}


function
 extendClass()
{
}

extendClass.prototype 
=
 
new
 baseClass();
var instance 

=
 
new
 extendClass();
instance.showMsg(); 

//
 显示baseClass::showMsg

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

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

 

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

下面是扩展实验2:

function
 baseClass()
{
    

this
.showMsg 
=
 
function
()
    {
        alert(

“
baseClass::showMsg
“
);   
    }
}


function
 extendClass()
{
    

this
.showMsg 
=
function
 ()
    {
        alert(

“
extendClass::showMsg
“
);
    }
}

extendClass.prototype 
=
 
new
 baseClass();
var instance 

=
 
new
 extendClass();

instance.showMsg();
//
显示extendClass::showMsg

 

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

 

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

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

 

答案是可以使用call:

extendClass.prototype 
=
 
new
 baseClass();
var instance 

=
 
new
 extendClass();


var
 baseinstance 
=
 
new
 baseClass();
baseinstance.showMsg.call(instance);

//
显示baseClass::showMsg

 

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

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

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

 

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

 

<
script type
=
“
text/javascript
“
>


function
 baseClass()
{
    

this
.showMsg 
=
 
function
()
    {
        alert(

“
baseClass::showMsg
“
);   
    }
   
    

this
.baseShowMsg 
=
 
function
()
    {
        alert(

“
baseClass::baseShowMsg
“
);
    }
}
baseClass.showMsg 

=
 
function
()
{
    alert(

“
baseClass::showMsg static
“
);
}


function
 extendClass()
{
    

this
.showMsg 
=
function
 ()
    {
        alert(

“
extendClass::showMsg
“
);
    }
}
extendClass.showMsg 

=
 
function
()
{
    alert(

“
extendClass::showMsg static
“
)
}

extendClass.prototype 
=
 
new
 baseClass();
var instance 

=
 
new
 extendClass();

instance.showMsg(); 
//
显示extendClass::showMsg


instance.baseShowMsg(); 
//
显示baseClass::baseShowMsg


instance.showMsg(); 
//
显示extendClass::showMsg



baseClass.showMsg.call(instance);

//
显示baseClass::showMsg static




var
 baseinstance 
=
 
new
 baseClass();
baseinstance.showMsg.call(instance);

//
显示baseClass::showMsg




<
/
script>

 

作者:轩脉刃(yjf512)
出处:(http://www.cnblogs.com/yjf512/)
版权声明:本文的版权归作者与博客园共有。欢迎转载阅读,转载时须注明本文的详细链接。 

 

[参考文章]

http://tech.ddvip.com/2009-05/1243588303121461.html

http://jetway.iteye.com/blog/56533

http://xiaofeizm55333.iteye.com/blog/80913

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155009.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • &0xff的原因

    &0xff的原因&0xff的目的

    2022年6月19日
  • 空格html代码快捷键,html的空格代码怎么写?教你如何使用空格nbsp代码[通俗易懂]

    空格html代码快捷键,html的空格代码怎么写?教你如何使用空格nbsp代码[通俗易懂]本篇文章为大家介绍的是HTML的空格代码的写法,“&nbsp;”代码的用法,还有几种空格方式的解释,都在文章中,现在开始往下看吧。首先,我们知道这HTML网页中插入多个空格间隔是需要特殊字符编码的。如果是直接敲入多个空格键的话,虽然看似代码中有了多个空格效果,但其实在浏览器中还是只有1个空格间隔位置的。接下来教大家如果输入html空格字符的话,多个空格字符是如何输入的?我们采用直接复制空格…

    2022年9月22日
  • pytest运行_ios自动清理缓存

    pytest运行_ios自动清理缓存前言pytest运行完用例之后会生成一个.pytest_cache的缓存文件夹,用于记录用例的ids和上一次失败的用例。方便我们在运行用例的时候加上–lf和–ff参数,快速运行上一

    2022年7月28日
  • No qualifying bean of type [XXX.XXX] found for dependency 解决方法「建议收藏」

    No qualifying bean of type [XXX.XXX] found for dependency 解决方法「建议收藏」源代码:@ServicepublicclassUserServiceimplementsUserServices{@AutowiredUserMapperuserMapper;publicbooleanAddUserInfo(Useruser){if(userMapper.insert(user)>0)

    2022年8月22日
  • win10jdk环境变量配置[通俗易懂]

    win10jdk环境变量配置[通俗易懂]在win10上安装jdk后,发现命令行中java-version命令可运行,但javac则提示“javac不是内部或外部命令……”,经过尝试发现需要将两个bin的路径都设置到环境变量中,而且需要使用绝对路径,不可以引用其他环境变量,例如我的环境变量设置是:C:\ProgramFiles(x86)\Java\jdk1.8.0_112\jre\bin;C:\ProgramFiles(

    2022年7月21日
  • Tomcat中的ResourceBundle国际化解析「建议收藏」

    Tomcat中的ResourceBundle国际化解析「建议收藏」一、ResourceBundle简介:资源束(ResourceBundle)是一个本地化对象。它封装了适用于本地环境的资源;这个类主要用来解决国际化和本地化问题。国际化和本地化可不是两个概念,两者都是一起出现的。可以说,国际化的目的就是为了实现本地化。比如对于“取消”,中文中我们使用“取消”来表示,而英文中我们使用“cancel”。若我们的程序是面向国际的…

    2022年7月12日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号