========================================================================

在学习JS的面向对象过程中,一直对constructor与prototype感到很迷惑,看了一些博客与书籍,觉得自己弄明白了,现在记录如下:

我们都知道,在JS中有一个function的东西。一般人们叫它函数。比如下面的代码

function Person(name)
{
alert(name);
}
Person('js');//js

上面的代码中,Person的表现的确跟一般的函数没有什么区别,接着看下面的代码

function Person(name)
{
this.name=name;
this.showMe=function()
{
alert(this.name);
}
};
var one=new Person('JavaScript');
one.showMe();//JavaScript

很多人见到了久违的new操作符,于是就叫Person为“类”,可是又没有关键字class的出现,觉得叫“类”有点勉强。于是退而求其次叫Person为类的构造函数。这些概念好像都没有错,之所以出现这样的情况,可能是因为大家都学习了传统的面向对象语言(c++,c#,java等),还有一种思维定势吧。为了让javascript也面向对象,要在javascript中找到与传统面向对象语言的影子。可是按照javascript的说法,function定义的这个Person就是一个Object(对象),而且还是一个很特殊的对象,这个使用function定义的对象与使用new操作符生成的对象之间有一个重要的区别。这个区别就是function定义的对象有一个prototype属性,使用new生成的对象就没有这个prototype属性

prototype属性又指向了一个prototype对象,注意prototype属性prototype对象是两个不同的东西,要注意区别。在prototype对象中又有一个constructor属性,这个constructor属性同样指向一个constructor对象,而这个constructor对象恰恰就是这个function函数本身。

有点头晕,看下图吧:

不相信可以看下面的代码:

function Person(name)
{
this.name=name;
this.showMe=function()
{
alert(this.name);
}
}; var one=new Person('js'); alert(one.prototype)//undefined
alert(typeof Person.prototype);//object
alert(Person.prototype.constructor);//function Person(name) {...};

上面的代码证明了one这个对象没有prototype属性。

我们接着看代码:

function Person(name)
{
this.name=name;
this.showMe=function()
{
alert(this.name);
}
}; Person.prototype.from=function()
{
alert('I come from prototype.');
} var one=new Person('js'); one.showMe();//js,这个结果没有什么好奇怪的
one.from();//I come from prototype.,这个结果有一点奇怪吧

要解释这个结果就要仔细研究一下new这个操作符了.var one=new Person('js');这个语句执行的过程可以分成下面的语句:

var one={};
Person.call(one,'js');

按照《悟透javascript》书中说的,new形式创建对象的过程实际上可以分为三步:

第一步是建立一个新对象(叫A吧);

第二步将该对象(A)内置的原型对象设置为构造函数(就是Person)prototype 属性引用的那个原型对象;

第三步就是将该对象(A)作为this 参数调用构造函数(就是Person),完成成员设置等初始化工作。

其中第二步中出现了一个新名词就是内置的原型对象,注意这个新名词跟prototype对象不是一回事,为了区别我叫它inobj,inobj就指向了函数Person的prototype对象。在person的prototype对象中出现的任何属性或者函数都可以在one对象中直接使用,这个就是javascript中的原型继承了

又头晕了,上图吧!

这样one对象通过内置的原型对象inobj就可以直接访问Person的prototype对象中的任何属性与方法了。这也就解释了上面的代码中为什么one可以访问form函数了。因为prototype对象中有一个constructor属性,那么one也可以直接访问constructor属性。

function Person(name)
{
this.name=name;
this.showMe=function()
{
alert(this.name);
}
}; Person.prototype.from=function()
{
alert('I come from prototype.');
} var one=new Person('js'); one.showMe();//js,这个结果没有什么好奇怪的
one.from();//I come from prototype.,这个结果有一点奇怪吧
alert(one.constructor);//function Person(name) {...}
alert(Person.prototype.constructor);//function Person(name) {...}

接着看继承是如何实现的。

function Person(name)
{
this.name=name;
this.showMe=function()
{
alert(this.name);
}
}; Person.prototype.from=function()
{
alert('I come from prototype.');
} function SubPerson()
{
}
SubPerson.prototype=new Person(); var subOne=new SubPerson();
subOne.from();//I come from prototype.
alert(subOne.constructor);//function Person(name) {...};
alert(SubPerson.prototype.constructor);//function Person(name) {...};

继承的实现很简单,只需要把子类的prototype设置为父类的一个(实例化)对象即可。注意这里说的可是对象哦!那么通过prototype属性实现继承的原理是什么呢?还是先看图形说明,然后编写代码进行验证。

注意:红色的方框就是把子类与父类链接起来的地方。这个就应该是传说中的prototype链了吧。下面有代码进行验证。

function Person(name)
{
this.name=name;
this.showMe=function()
{
alert(this.name);
}
}; Person.prototype.from=function()
{
alert('I come from prototype.');
}
var father=new Person('js');//为了下面演示使用showMe方法,采用了js参数,实际多采用无参数
alert(father.constructor);//查看构造函数,结果是:function Person(name) {...};
function SubPer()
{
}
SubPer.prototype=father;//注意这里
SubPer.prototype.constructor=SubPer; var son=new SubPer();
son.showMe();//js
son.from();//I come from prototype.
alert(father.constructor);//function SubPer(){...}
alert(son.constructor);//function SubPer(){...}
alert(SubPer.prototype.constructor);//function SubPer(){...}

根据上图的prototype链,还有代码的结果,我想应该明白为什么使用prototype能够实现

JS中的继承了吧。

关于JS中的constructor与prototype的更多相关文章

  1. 分析js中的constructor 和prototype

    在javascript的使用过程中,constructor 和prototype这两个概念是相当重要的,深入的理解这两个概念对理解js的一些核心概念非常的重要. 我们在定义函数的时候,函数定义的时候函 ...

  2. 深入分析js中的constructor 和prototype

    在javascript的使用过程中,constructor 和prototype这两个概念是相当重要的,深入的理解这两个概念对理解js的一些核心概念非常的重要. 我们在定义函数的时候,函数定义的时候函 ...

  3. 【JavaScript】关于JS中的constructor与prototype

    最初对js中 object.constructor 的认识: 在学习JS的面向对象过程中,一直对constructor与prototype感到很迷惑,看了一些博客与书籍,觉得自己弄明白了,现在记录如下 ...

  4. 【推荐】关于JS中的constructor与prototype【转】

    最初对js中 object.constructor 的认识: 在学习JS的面向对象过程中,一直对constructor与prototype感到很迷惑,看了一些博客与书籍,觉得自己弄明白了,现在记录如下 ...

  5. JS中的constructor与prototype

    http://www.cnblogs.com/qiantuwuliang/archive/2011/01/08/1930548.html 在学习JS的面向对象过程中,一直对constructor与pr ...

  6. JS中的constructor 和 prototype

    object.constructor :对象的constructor 属性引用了该对象的构造函数. //例如,用Array()构造函数创建了一个数组,那么a.constructor 引用的就是Arra ...

  7. js中的constructor 和prototype

    参考 http://www.cnblogs.com/yupeng/archive/2012/04/06/2435386.html function a(c){ this.b = c; this.d = ...

  8. js中关于constructor与prototype的理解

    1.①__proto__和constructor属性是对象所独有的:② prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性. 2. ...

  9. 关于JS中的constructor与prototype{转}

    http://www.cnblogs.com/qiantuwuliang/archive/2011/01/08/1930548.html http://www.cnblogs.com/yupeng/a ...

随机推荐

  1. GoogleMapApi 发布后提示安全问题

    今天日本那边发过来一个Bug说是Google Map打不开,提示安全问题. 最后发现,日本那边的发布路径如下: https:xxxxx.gspserver.co.jp 而Source中Google M ...

  2. linux的一点小随笔

    随意写的一些东西,也就为以后自己可能看看... 1.vim安装,sudo apt-get install vim-gtk,于是vim就安装好了.当然在我电脑上还出现了gvim,简单的vim配置(etc ...

  3. python Django 学习笔记(五)—— Django admin自动管理界面

    1,激活管理界面 修改settings.py MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.c ...

  4. Redis 配置文件 redis.conf 项目详解

    Redis.conf 配置文件详解 # [Redis](http://yijiebuyi.com/category/redis.html) 配置文件 # 当配置中需要配置内存大小时,可以使用 1k, ...

  5. eclipse导出Runnable Jar File在Launch Configuration中找不到类

    1.只要选择中你需要Launch Configuration中出现的类,右击Run AS -- Java Application 再次. 2.点击导出Export的时候,就可以看到类在列表中出现了. ...

  6. oracle 修改表空间存储路径

    [root@yoon ~]# more /etc/oracle-releaseOracle Linux Server release 5.7 Oracle Database 11g Enterpris ...

  7. hdu 2102 A计划

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2102 A计划 Description 可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸 ...

  8. 用js进行日期的加减

    如题,开始查了查js的使用文档,但没发现可以直接用的函数,于是就想自己写函数来着,这就要涉及到每个月天数的判断,如果是2月份的话,还要涉及到闰年的判断,虽然不复杂但我想js应该不会这么低级,于是查了下 ...

  9. SQL Server 2008 R2 主从数据库同步

    一.准备工作: 主数据库服务器: OS:Windows Server 2008 R2    DB: SQL Server 2008 R2 Hostname : CXMasterDB IP: 192.1 ...

  10. Knockout : 实现复杂的web聊天窗体

    公司以前一个同事写的这个聊天的窗体,由于是采用了html拼接的方式,外加处理的时候没有合理的划分职责,导致页面js代码量非常庞大(1500行左右).现在这哥们离职了,苦的是我们剩下的人,不多说,我先去 ...