Prototype

Prototype是js面向对象中实现多态的核心,或者说是区别于普通面向对象语言如java等的灵魂所在,越是这种玩意,越是坑,因为如果对这些理解不深,反而会被它的一些表面现象所迷惑,导致各种深层bug,不断入坑。
这里对自己之前所做的项目中所用到的此部分内容做一些总结

思考

开篇我想就我之前用JS的一些体会,简单说几个点

  • 人们常说,JS中万物皆对象,所以很多时候如果我们用Java等语言的(类-对象)逻辑去套JS反而会让自己无法理解。
    这里,我们需要破而后立,先树立一个概念,JS万物皆对象,记住是对象,不是类!即使我们会定义一些function,然后使用new去定义初始化一些对象,但是这里的function仍然是对象,只是刚好能够用来帮助初始化一类对象而已

JS中的对象

通常来说,javascript中的对象就是一个指向prototype的指针和一个自身的属性列表。javascript创建对象时采用了写时复制的理念。
只有 构造器 才具有prototype属性,原型链继承就是创建一个新的指针,指向构造器的prototype属性。
prototype属性之所以特别,是因为javascript时读取属性时的遍历机制决定的。本质上它就是一个普通的指针。
构造器包括以下对象:

  1. Object
  2. Function
  3. Array
  4. Date
  5. String

Prototype

Prototype是啥

这里强烈推荐参考[关于JS中的constructor与prototype][],这应该是全网写的最直白的,帮助我们小白看懂其中的逻辑
首先,prototype我的理解是一个对象的属性,根据上文,我们知道只有构造器才有prototype属性。
prototype属性又指向了一个prototype对象,注意prototype属性与prototype对象是两个不同的东西,要注意区别。在prototype对象中又有一个constructor属性,这个constructor属性同样指向一个constructor对象,而这个constructor对象恰恰就是这个function函数本身。
看图(本文图均出自[关于JS中的constructor与prototype][]文章,下文不再说明)


prototype和构造器

Sample Code:

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有(Function是构造器),并且prototype中有只想具体构造函数的属性

JS中对象的定义过程

按照《悟透javascript》书中说的,new形式创建对象的过程实际上可以分为三步:
第一步是建立一个新对象(叫A吧);
第二步将该对象(A)内置的原型对象设置为构造函数(就是Person)prototype 属性引用的那个原型对象;
第三步就是将该对象(A)作为this 参数调用构造函数(就是Person),完成成员设置等初始化工作。
其中第二步中出现了一个新名词就是内置的原型对象,注意这个新名词跟prototype对象不是一回事,为了区别我叫它inobj,inobj就指向了函数Person的prototype对象。在person的prototype对象中出现的任何属性或者函数都可以在one对象中直接使用,这个就是javascript中的原型继承了。


对象与Prototype

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

JS继承(原型链)

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


继承(原型链)

Sample Code:

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

这个所谓的原型链就是从最下方的子对象开始,往自己的原型上溯。找调用的属性或者方法,如果找不到就继续找原型的原型。一直下去。这个比较好理解,和普通的父类回溯是差不多的逻辑。

What's More

至此,prototype的大概应该有所理解了。那么还有几个非常重要的细节,并且是使用最多的特性需要再强调一下,其实已经隐藏在上面的code里了。

  1. 每一个对象(被构造器创造出来的对象)姑且成为myObj,即new+某个function弄出的对象,可以直接访问constructor属性,这玩意指向的就是构造器
    但是同时,这玩意是没有prototype属性的,因为prototype只在构造器里才有。不过我们可以这样找到他的prototype,那就是myObj. constructor. prototype
  2. 函数对象中自身声明的方法和属性与prototype声明的对象有什么差别?
    有下面几个差别:
  • 自身声明的方法和属性是 静态的, 也就是说你在声明后,试图再去增加新的方法或者修改已有的方法,并不会 对由其已经创建的对象产生影响
  • 而prototype可以动态地增加新的方法或者修改已有的方法, 从而是 动态的 ,一旦 父函数对象 声明了相关 的prototype属性,由其创建的对象会 自动继承 这些prototype的属性.

总结下,结合上文开头所述,prototype是指针,指向的是一个prototype对象。而具体的调用在在具体使用的时候,才去根据原型链一个一个去找的。所以在你update了prototype的属性和方法后,所有继承了这个prototype的对象都能动态的自动继承这些新update的玩意。这个才是JS作为动态的面向对象语言最有价值的玩意

Javascript的方法

JS中有三类方法

a. 类方法
b. 对象方法
c. 原型方法

Sample Code:

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

参考文章
[JS中的prototype][]
[关于JS中的constructor与prototype][]
[javascript必知必会之prototype][]
[JS中的prototype]:http://www.cnblogs.com/yjf512/archive/2011/06/03/2071914.html
[关于JS中的constructor与prototype]:http://blog.csdn.net/niuyongjie/article/details/4810835
[javascript必知必会之prototype]:http://www.cnblogs.com/mindsbook/archive/2009/09/19/javascriptYouMustKnowPrototype.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容