程序如同艺术 ,源于生活而又高于生活…
每位coder就像追寻真理的苦行僧,他们谱写着自己对于生活的理解。
并在程序的世界里,追寻真理,感悟真理。
《至简 · 一》原型-原型链
第一次接触编程是在大学,那时是从c语言开始的,当时对于程序没有那么多的理解,更多的是新鲜。之后也学习了OOP,还有数据结构,但是最终对c语言还是没能进行更多的探究。
而是选择了前端进行深入,我喜欢从事有关美的事物,所以在大学期间,多数也算是“不务正业”,当初爱上了游戏场景设计,地形编辑。它们不同于当初写的c程序,因为它们表现的更直观。之后也经历了种种,也学习了种种。最终走上了前端这条路我想还是因为美。现在依然记得在做ASP时,对于网页美感的苛求,我敢肯定在这个点上花费的时间严重多于对于后台Server的设计。
回归正题,来讲述今天的话题
-
万物皆对象 :这句话大概经常听到了,这句话是从程序的映射到现实的写照。但是却非最高境界,佛曰四大皆空。 神秀曰:身是菩提树,心如明镜台,时时勤拂拭,莫使惹尘埃。 慧能曰:菩提本无树,明镜亦非台,本来无一物,何处惹尘埃。
javascript的世界中,对象就如同这佛法,源于一个null。 -
道生一,一生二,二生三,三生万物
何谓道,这是个还要继续追寻的真理。目前还不明确
还是说null吧,null就如同这个道,如同宇宙出生于混沌,null是什么,讲不清,道不明,null就是null,它既是无,又存在。
万物皆对象,其他的对象,通过构造函数创造,于是乎又诞生了Object和Function,他们彼此结合,提供了原型(prototype)和构造器(constructor),一个为子孙提供基因,一个负责制造万千子孙,如果说null是上帝,那么他们俩就如同亚当和夏娃。
- 什么是原型prototype
什么是原型,通俗的讲,就是一个模子,要制作一件陶器,得先有个模子,照着这个模子,才能批量的生产,而prototype就是对象的模子,既然是模子,那么它也是存在的,它也是对象。构造函数,负责批量的生产。
如何找到这个模子呢,在js中函数function存在一个属性,即prototype属性,可以通过函数来访问。记住,只有函数存在prototype属性,例如:
function Person(){}
var person = new Person();
在浏览器里观察
可以看到Person通过prototype属性找到它的原型对象即Person.prototype,原型有通过constructor指向Person。意思就如同Person说,我的原型是Person.prototype,而Person.prototype说Person是我的构造器。就像酱紫:
可是prototype是只有function才有的属性,我们如何对每个对象该如何追根溯源呢?难道他们是猴子吗,是从石头缝里蹦出来的吗?emmm…这是一个问题。
- 真正的基因__proto__
每个对象都有着__proto__属性,它的作用是什么呢?就是告诉我们不要忘了自己的根儿…
接着看刚才那副图片
看到了一个浅紫色的__proto__,这是什么呢,__proto__指向了Object这能说明什么呢?先不急。
再来看看下一个
function Person(){}
var person = new Person();
举个栗子
我们通过构造函数Person实例化出一个新的小person,小person年少无知忘了自己亲爹是谁了,就问他面前的Person构造函数
说,“你是我爹吗?”
构造函数上去就是一嘴巴子,“完蛋玩意,我是你妈啊 ! 是我生的你啊,真完蛋!”。
小person明白了,哦 ,你是我妈,那我爹是谁啊?
他妈又是一嘴巴子说:你爹是Person.prototype!
谁知小person很气愤的说:“你说我爹是Person.prototype那就是吗?我不信! 万一不是呢…”。
只好拉着小person去做了基因检测,发现小person身上的基因__proto__的确是指向Person.prototype ,
至此,小person终于找到了自己的亲爹。
开个玩笑哈,方便去理解,这里的爹指的就是原型,就是那个模子。关系图如下。
对于__proto__属性,官方不建议使用,不建议对此属性进行操作,__proto__属于内部属性。若要检查对象的原型,可以通过
- instanceof 运算符返回一个布尔值,表示一个对象是否由某个构造函数创建。
- Object.isPrototypeOf()只要某个对象处在原型链上,也会返回一个bool值,若为true就说明对象是其原型。
- 当然还有别的方法
借此,我们就可以顺着这个基因链顺藤摸瓜,找到每一个对象的祖先。再次说一下,__proto__是每个对象都有的属性,function也是对象,也不例外。来试一试吧,来看看大person的爹是谁,小person妈妈(构造函数)的爹又是谁。
上面可以看到构造函数Person的祖先,就是Function原型对象。
可以看到小person祖先是Person.prototype原型对象,Person.prototype原型的祖先是Object.prototype原型对象。
并且可以看到Function.prototype的祖先也是Object.protype原型对象。
也就是说Object.protype原型对象,是所有对象的的最祖先原型,即太太太太爷爷。
我们还可以继续追根溯源,看看他们的祖先,太太太太爷爷的爹到底是谁
最终发现对象的祖先是来源于一个null,还当真映了佛门那句,四大皆空,amazing。
借此,以一幅图,来展示整个原型的关系结构:
看到这个是不是有些蒙蔽,这啥玩意指来指去的,什么鬼。好吧,我承认这个图是有些复杂了,但是绝对是我良心之作。
为了方便于理解,我又画了一个浓缩版的。
大图是重点,可以看出,像这种,一个原型对象,作为另一个实例的原型,而原型对象,又是另一个原型的实例,通过__proto__属性链接,最终形成的这种层层递进的链式结构,也就是原型链的原理。
emmmm…至此关于有关于原型的环节就说到这。
若有错误,望各位前辈指正。