`
yiyanwan77
  • 浏览: 187337 次
  • 性别: Icon_minigender_1
  • 来自: 威海
社区版块
存档分类
最新评论

js contructor and prototype

 
阅读更多

最初对js中 object.constructor 的认识:

 

 

 

 

 

 

 

在学习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中的继承了吧。

 

 

 

 

摘自:http://blog.csdn.net/niuyongjie/archive/2009/11/15/4810835.aspx

分享到:
评论

相关推荐

    讲解JavaScript的面向对象的编程

    1. 下载解压之后,首先打开Contructor and object used.html文档,使用IE运行之后,查看原代码,代码中一行注释一行代码说明了this与prototype关键在使用function数据类型来定义JavaScript类的成员变量和普通方法的...

    FPS contructor

    Create any weapon you could imagine, from an automatic rifle to an orbital laser, and have them working in minutes! Simple to use, but flexible enough to make the game YOU want to make.

    Javascript的构造函数和constructor属性

    很显然,这个时候obj的constructor已经不再是创建它的函数,注意到obj.name也是undefined,因此修改构造函数的prototype的contructor并不会影响构造函数所产生的对象。真正的原因是:一个对象的constructor是它的...

    sqlserver JDBC架包

    SQL Server JDBC驱动架包是微软公司为Java应用程序提供的一种连接SQL Server数据库的接口,它允许Java开发者使用标准的Java编程语言来访问和操作SQL Server数据库。JDBC(Java Database Connectivity)是Java平台中...

    delphi2-delphi2010 全支持 dcu 装换 pas

    + Delete procedure, contructor, destructor frame 2002-07-18 + Procedure variable const + Now can distinguish: vc1: PChar ='test'; vc2: PChar = @vc1; 2002-05-28(Ver1.1) + Now correctly process ...

    TIL:今天我学到了

    今天我学到了 DK的Because정정하여Because因为我们的大脑XD,我们经常忘记我们学到的东西 :memo: 分类目录 前端 后端 工具 基本知识 算法 :raising_hands: 前端 ...contructor(){}在类中的工作方式非常相似。

    qmlcore-android:QMLCore本机android运行时(无DOMHTMLWebView)

    contructor ( optional parent ) { /* creates and adds this element to parent */ } append ( element ) { /*adds child*/ } remove ( ) { /*remove element from current parent */ } style ( name , value

    browserify-cordova:科尔多瓦中的浏览器和良好实践

    browserify-cordova 科尔多瓦中的浏览器和良好实践动机我注意到许多在中构建应用程序的框架都是一团糟。 因为它们是在您向最终用户发送过多不必要的内容时构建的。... The MSL for contructor the icons/logo

    renamer-garden-tool:一种轻松迭代项目文件夹并将它们重命名为附加数字的相同字符串的工具

    安装npm install renamer-garden-tool 用法 var Renamer = require('renamer-garden-tool')Renamer.help() // static method (Function on the contructor/class not the instance)或者 var renamer = new Renamer()...

    xmljava系统源码-SpringInAction4:《SpringInAction4th》学习笔记

    contructor, autodetect 可以在一个应用上下文中定义多个配置文件,每个配置文件设置自己的默认自动装配策略(default-autowire) 如果使用constructor自动装配策略,就不能混合使用constructor-arg 注解方式可以实现...

    Java基础知识面试题系列一.docx

    public Tom(){System.out.println("Tom contructor");} public static void main(String args[]){new Tom();} } ``` 运行这段代码将按照上述顺序打印信息。 4. **Java中的作用域**:Java中有四种基本的作用域...

Global site tag (gtag.js) - Google Analytics