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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • C++ SetTimer

    C++ SetTimer我搞了好久 最终也没成功的让SetTimer 回调一个非静态成员函数不过问题是解决了那就是把成员函数和要用到的那个成员变量换成静态了(有点拆东墙补西墙了)不过方法肯定是有的UINT_PTRSetTimer(HWNDhWnd,//窗口句柄UINT_PTRnIDEvent,//定时器ID,多个定时器

    2025年8月14日
    3
  • webpack打包优化_webpack打包及部署

    webpack打包优化_webpack打包及部署2019独角兽企业重金招聘Python工程师标准>>>…

    2022年10月21日
    6
  • Unity | Cinemachine FreeLook Camera「建议收藏」

    Unity | Cinemachine FreeLook Camera「建议收藏」FreeLookCamera是可以基于第三人称视角进行自由观察的虚拟相机。如下图所示,自由视角相机有上中下三个红圈,我们可以通过修改CinemachineFreeLook组件中的值来修改红圈的高度及大小。三个红圈由一个纵向的红线相连。通过改变YAxis及XAxis的Value可以修改虚拟相机的视角。 SplineCurvature决定纵向的紧绷状态。 TopRig、MiddleRig、BottomRig即三个红圈的属性。在CinemachineFreeL…

    2022年5月28日
    167
  • visual studio2019的安装以及使用

    visual studio2019的安装以及使用一 下载安装包下载地址选择 visualstudio 的 community 版本二 下载好后运行三 组件的选择如果是用来学 C C 的话 选择以下两个就够了之后如果还需要其他一些功能的话 可以后续在进行添加 打开 visualstudio 进入修改四 进行安装如果不需要修改安装位置的话点击安装就可以了 不过由于 vs2019 占用的空间较大最好不要装在

    2025年7月4日
    4
  • 使用Boostrap V4,左侧菜单栏可缩进,并根据屏幕宽度自适应大小。[通俗易懂]

    使用Boostrap V4,左侧菜单栏可缩进,并根据屏幕宽度自适应大小。[通俗易懂]使用Boostrap V4,左侧菜单栏可缩进,并根据屏幕宽度自适应大小。

    2022年4月21日
    44
  • hibernate和mybatis的区别及特点_hibernate配置文件中,不包含下面的

    hibernate和mybatis的区别及特点_hibernate配置文件中,不包含下面的很长一段时间,网上有很多关于Hibernate与Mybatis孰优孰劣的争论,两个阵营的人谁也不能说服谁,每个人的理由都很有道理。今天,我分享的主题是:在一个项目中同时使用Hibernate和Mybatis两个ORM框架。作为一个开发者,没有必要花费过多的时间去证明技术无用论,当你开始指责某个框架垃圾,另外一个框架最好时,隐性的暴露出你对某个框架没有深入的研究,无知的指责对于技术的提升没有…

    2025年8月29日
    5

发表回复

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

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