【推荐】关于JS中的constructor与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函数本身。

有点头晕,看下图吧:

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

按 Ctrl+C 复制代码

代码

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) {...};

按 Ctrl+C 复制代码

上面的代码证明了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/article/details/4810835

JS原型连的更多相关文章

  1. JS原型链

    JS作为发展了多年了对象语言,支持继承,和完全面向对象语言不同的是,JS依赖原型链来实现对象的继承. 首先JS的对象分两大类,函数对象和普通对象,每个对象均内置__proto__属性,在不人为赋值__ ...

  2. 深入分析JS原型链以及为什么不能在原型链上使用对象

    在刚刚接触JS原型链的时候都会接触到一个熟悉的名词:prototype:如果你曾经深入过prototype,你会接触到另一个名词:__proto__(注意:两边各有两条下划线,不是一条).以下将会围绕 ...

  3. 【09-23】js原型继承学习笔记

    js原型继承学习笔记 function funcA(){ this.a="prototype a"; } var b=new funcA(); b.a="object a ...

  4. js原型

    1.js基本类型和对象类型 js的简单类型包括数字(其中NaN为数字类型).字符串(类似'A'为字符,js没字符类型).布尔值.null值和undefined值.其他所有的值都是对象.数字.字符串和布 ...

  5. js原型链与继承(初体验)

    js原型链与继承是js中的重点,所以我们通过以下三个例子来进行详细的讲解. 首先定义一个对象obj,该对象的原型为obj._proto_,我们可以用ES5中的getPrototypeOf这一方法来查询 ...

  6. JS 原型链图形详解

    JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...

  7. js原型解析

    我们都知道javascript因为具有了继承以及变量等等一系列的特性之后才被人们认为具有一门编程语言的资格,在后续的不断发展中,js在原生的基础上扩展了基于jquery等等的库,甚至衍生了像node. ...

  8. 深入理解JS原型链与继承

    我 觉得阅读精彩的文章是提升自己最快的方法,而且我发现人在不同阶段看待同样的东西都会有不同的收获,有一天你看到一本好书或者好的文章,请记得收藏起来, 隔断时间再去看看,我想应该会有很大的收获.其实今天 ...

  9. 学习zepto.js(原型方法)

    学习zepto.js(原型方法)[1] 转载 新的一周,新的开始,今天来学习一下zepto里边的原型方法,就是通过$.进行调用的方法,也是可以通过$.fn进行扩展的方法: $.camelCase(): ...

  10. js原型链部分详细使用说明案例

    1. 'index.html'文件 ```html <!DOCTYPE html> <html lang="en"> <head> <me ...

随机推荐

  1. setImageResource和setImageDrawable区别

    ImageView设置图片的方式有很多钟,可以在xml里面写android:src=”@drawable/xxx”,也可以在java代码里面设置. 在java里面的设置方式也有多种,方法包括:setI ...

  2. MySql相关及如何删除MySql服务

    又会一招–如何删除MySql服务 进入“控制面板->管理工具->服务”查看才发现,虽然MYSQL已经卸载了,但是MYSQL服务仍然残留在系统服务里.又不想改服务名,改怎么办呢. 后来上百度 ...

  3. Web服务器(Apache)虚拟主机的配置

    一.定义    所谓虚拟主机是指在一台服务器里运行几个网站,提供WEB.FTP.Mail等服务.    二.虚拟主机的实现方法有三种:    基于IP的方法,基于主机名的方法和基于端口的法官法.    ...

  4. [LeetCode] Ugly Number II (A New Question Added Today)

    Write a program to find the n-th ugly number. Ugly numbers are positive numbers whose prime factors ...

  5. Tkinter教程之Listbox篇

    本文转载自:http://blog.csdn.net/jcodeer/article/details/1811310 #Tkinter教程之Listbox篇#Listbox为列表框控件,它可以包含一个 ...

  6. [apkAnalyzer] 查看APK包名

    最近项目中要用到APK的包名,必应到apkAnalyzer这个软件可以用,下载解压后,看到这么些jar,bat文件不知道怎么用. 参考了这篇文章,看的也不甚明白,最后还是试出来了,这里记录一下. 首先 ...

  7. Spring Framework 中启动 Redis 事务操作

    背景: 项目中遇到有一系列对Redis的操作,并需要保持事务处理. 环境: Spring version 4.1.8.RELEASE Redis Server 2.6.12 (64位) spring- ...

  8. JAVA虚拟机之类加载器

    转载请声明:原文转自http://www.cnblogs.com/xiezie/p/5909570.html 1.JVM的生命周期 1.1 JVM的生命周期和程序的生命周期一致 1.2 JVM结束生命 ...

  9. Spark SQL概念学习系列之为什么使用 Spark SQL?(二)

    简单地说,Shark 的下一代技术 是Spark SQL. 由于 Shark 底层依赖于 Hive,这个架构的优势是对传统 Hive 用户可以将 Shark 无缝集成进现有系统运行查询负载. 但是也看 ...

  10. 斜率DP题目

    uva 12524 题意:沿河有n个点,每个点有w的东西,有一艘船从起点出发,沿途可以装运东西和卸载东西,船的容量无限,每次把wi的东西从x运到y的花费为(y-x)*wi; 问把n个点的东西合并成k个 ...