JavaScript_Object_Oriented
proto成员
var array1 = [1, 2, 3]
数组对象在JavaScript引擎中的对象模型
prototype成员
Base的对象模型
obj的对象模型
new 操作符干了三件事
var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);
// 第一行,我们创建了一个空对象obj
// 第二行,我们将这个空对象的__proto__成员指向了Base函数对象prototype成员对象
// 第三行,我们将Base函数对象的this指针替换成obj,然后再调用Base函数,于是我们就给obj对象赋值了一个id成员变量,这个成员变量的值是”base”
模拟类
如果我们给Base.prototype的对象添加一些函数会有什么效果呢?
Base.prototype.sayHello = function() {
return "hello " + this.id;
}
那么当我们使用new创建一个新对象的时候,根据proto的特性,toString这个方法也可以做新对象的方法被访问到。
构造子中,我们来设置‘类’的成员变量(例如:例子中的id),构造子对象prototype中我们来设置‘类’的公共方法。于是通过函数对象和Javascript特有的proto与prototype成员及new操作符,模拟出类和类实例化的效果。
Pseudoclassical继承
我们模拟类,那么继承又该怎么做呢?其实很简单,我们只要将构造子的prototype指向父类即可。例如我们设计一个Derive 类。如下
function Derive(id) {
this.id = id;
}
Derive.prototype = new Base();
Derive.prototype.test = function(id){
return this.id === id;
}
var newObj = new Derive("derive");
newObj的对象模型是
这样我们的newObj也继承了基类Base的sayHello方法,并且具有自身的成员id。
Prototypal继承
这是Javascript的另外一种继承方式,这个继承也就是之前陈皓文章《Javascript 面向对象编程》中create函数,非常可惜的是这个是ECMAScript V5的标准,支持V5的浏览器目前看来也就是IE9,Chrome最新版本和Firefox。虽然看着多,但是做为IE6的重灾区的中国,我建议各位还是避免使用create函数。好在没有create函数之前,Javascript的使用者已经设计出了等同于这个函数的。例如:我们看看Douglas Crockford的object函数。
function object(old) {
function F() {};
F.prototype = old;
return new F();
}
var newObj = object(oldObject);
var base ={
id:"base",
toString:function(){
return this.id;
}
};
var derive = object(base);
如何形成这样的对象模型,原理也很简单,只要把object这个函数扩展一下,就能画出这个模型,怎么画留给读者自己去画吧。
这样的继承方式被称为原型继承。相对来说要比Pseudoclassical继承来的简单方便。ECMAScript V5正是因为这原因也才增加create函数,让开发者可以快速的实现原型继承。
上述两种继承方式是Javascript中最常用的继承方式。通过本文的讲解,你应该对Javascript的OO编程有了一些‘原理’级的了解了吧