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)
上一篇 2022年7月1日 下午11:46
下一篇 2022年7月2日 上午6:00


相关推荐

  • rpm 安装 忽略依赖_rpm卸载软件忽略循环依赖

    rpm 安装 忽略依赖_rpm卸载软件忽略循环依赖今天由于某些原因需要卸载掉服务器上的php软件,然后我使用下面命令显示出本机安装的所有和php相关的软件,如下:iteblog$rpm-qa|grepphpphp-mysqlnd-5.6.25-0.1.RC1.el6.remi.x86_64php-fpm-5.6.25-0.1.RC1.el6.remi.x86_64php-pecl-jsonc-1.3.10-1.el6.remi.5.6…

    2026年2月15日
    5
  • java与数据库连接的步骤_java与数据库的连接怎么实现

    java与数据库连接的步骤_java与数据库的连接怎么实现1.加载驱动Class.forname(数据库驱动名);2.建立数据库连接使用DriverManager类的getConnection()静态方法来获取数据库连接对象,其语法格式如下所示:Connectionconn=DriverManager.getConnection(Stringurl,Stringuser,Stringpass);其中url–数据库连接字符串….

    2025年12月8日
    5
  • NoSQL 数据库产品学习总结(一)「建议收藏」

    NoSQL 数据库产品学习总结(一)

    2022年2月3日
    57
  • linux安装weget命令,linux安装wget命令

    linux安装weget命令,linux安装wget命令wget命令是linux系统下的一个常用命令。下面由学习啦小编为大家整理了linux安装wget命令的相关知识,希望大家喜欢!linux安装wget命令方法一debian或者ubuntu:sudoapt-getinstallwgetcentos:sudoyum-yinstallwgetlinux安装wget命令方法二我们先安装linux系统比如centos7.1里面有的就…

    2022年10月16日
    4
  • sql删除或清空表数据[通俗易懂]

    sql删除或清空表数据[通俗易懂]sql删除或清空表数据一、sql清空表数据的三种方式:二、语法一、sql清空表数据的三种方式:我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:1、truncate–删除所有数据,保留表结构,不能撤销还原2、delete–是逐行删除速度极慢,不适合大量数据删除3、drop–删除表,数据和表结构一起删除,快速二、语法truncatetable表名deletefrom表名deletefrom表

    2022年4月30日
    55
  • 点击scrollview释放键盘触发touchesBegan方法

    点击scrollview释放键盘触发touchesBegan方法scrollView 本身继承了touch的响应事件,要从新自定义scrollView 的响应事件。所以添加一个手势事件:-(void)addGestureRecognizer{  UITapGestureRecognizer*sigleTap=[[UITapGestureRecognizeralloc]initWithTarget

    2022年7月25日
    13

发表回复

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

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