日期:2014-05-16  浏览次数:20376 次

笑学原型——Object-Oriented JavaScript(Part 1)


原型语言


一、什么是原型语言

悟空问观音:什么是原型语言?
观音:一切都是对象,对象继承对象,这就是原型语言。
悟空:好,明白
唐僧:?详细一点来说,
1 ?只有对象,没有类;对象继承对象,而不是类继承类。

2 ?“原型对象”是核心概念。原型对象是新对象的模板,它将自身的属性共享给新对象。一个对象不但可以享有自己创建时和运行时定义的属性,而且可以享有原型对象的属性。

3 ?每一个对象都有自己的原型对象,所有对象构成一个树状的层级系统。root节点的顶层对象是一个语言原生的对象,只有它没有原型对象,其他所有对象都直接或间接继承它的属性。
...
悟空:!@#¥%……


二、谁来创建对象
A: 一切都是对象,那依靠谁来生成对象呢?
B:人类的世界都是人,谁来生产人
A: 人来生人啊!这不是2B的问题嘛!
B: 那你刚才问啥,2b?
上帝之音: 原型的世界,对象创建对象。

原型语言创建有两个步骤
1. 使用"原型对象"作为"模板"生成新对象
这个步骤是必要的,这是每个对象出生的唯一方式。以原型为模板创建对象,这也是"原型"(prototype)的原意。
2. 初始化内部属性
这一步骤不是必要的。通俗点说,就是,对"复制品"不满意,我们可以"再加工",使之获得不同于"模板"的"个性"。

这两个步骤很自然,也很好理解,比使用类构造对象从概念上简单得多了,而且更符合自然。对于习惯了java基于类的面向对象的语言的程序员, 这种"新颖"的生成对象的方式一定会让他们感到好奇。

三、内存对原型说,我爱死你了
内存说,自从有了原型,腰不酸了,腿不疼了,跳楼也有劲了

使用原型,能复用代码,节省内存空间?

举个例子,存在旧对象oldObject,它有一个属性name,值是’Andy’, 和一个名为getName()的方法,如果以该对象为原型创建一个新对象,
 newObject = create(oldObject);
?
那么新对象newObject同样具有属性name,值也是’Andy’,也有一个方法getName()。值得注意的是,newObject并不是在内存中克隆了oldObject,它只是引用了oldObject的属性,?导致实际的效果好像"复制"了newObject一样。

?newObject = create(oldObject);创建的对象newObject只有一个属性,这个属性的值是原型对象的地址(或者引用),如下图所示。


四、原型链
本屌在街上见到一个战斗只有5的渣,准备欺负他找点乐子,没想到,他说:我爸是李刚,我爷是胡哥,我曾爷爷也是...

原型世界的对象也一样,对象不是一个人在战斗,他在原型链上的关系能给予他强大的力量。

当对象访问属性的时候,如果在内部找不到,那么会在原型对象中查找到属性;如果原型对象中仍然找不到属性,原型对象会查找自身的原型对象,如此循环下去,直至找到属性或者到达顶级对象。对象查找属性的过程所经过的对象构成一条链条,称之为原型链。newObject,oldObject和topObject就构成一条原型链。

下面列出newObject的3种的查找属性情况

newObject查找name,
1 内部找不到,到原型对象中查找
2 oldObject中查找到了name,成功返回;

newObject查找toString
1 内部找不到,到原型对象中查找
2 oldObject中查找不到toString,到原型对象中查找
3 topObject中查找到了toString,成功返回;

newObject查找valueOf
1 内部找不到,到原型对象中查找
2 oldObject中查找不到valueOf,到原型对象中查找
3 topObject中还是找不到,而且topObject是顶层对象,所以返回错误或者空值。

对象会通过原型链动态地查找属性,对象的所拥有的属性是动态的。
如果原型链上的一个对象发生的改变,那么这个改变也会马上会反应到在原型链中处于该对象下方的所有对象,这是一个非常有用的特性。

五、术语: 继承
对象A问上帝:继承是什么?
上帝问A ? ? ?:你知道你为什么那么帅吗?
?A ? ? ? ? ? ? ?:不知道
上帝 ? ? ? ? ? :你看看正在看博客的那位超级帅哥,他是你爹,你理解什么是继承了吧

在java中 通过语句class Cat extends Animal定义Cat类继承Animal类,Cat类产生的实例对象便拥有了Animal类中定义的属性。类似地,在基于原型的语