本文假定你有了一定的javascript面向对象的基础了,就不过多的关于javascript面向对象基础的介绍。
首先,让我们来举个例子,做个传统意义上的javascript的继承。
/**
* @description 新建个“人类”的类,拥有三个初始的属性,姓名,年龄,性别。
* 在其构造方法中,我们可以对这些属性做一个初始化的工作。
*
* @param {string} name
* @param {number} age
* @param {string} gender
*/
function Humen(name, age, gender) {
this.age = 0 || age;
this.name = '' || name;
this.gender = '' || gender;
}
Humen.prototype.eat = function() {}
Humen.prototype.sleep = function() {}
/**
* @description 新建个“超人”的类,拥有三个初始的属性,姓名,年龄,性别。
* 在完成了和人类相同的属性的同时,他比人类还多了一个属性“power”,能量值。
*
* @param {string} name
* @param {number} age
* @param {string} gender
* @param {number} power
*/
function SuperMen(name, age, gender, power) {
this.age = 0 || age;
this.name = '' || name;
this.gender = '' || gender;
this.power = '' || power;
}
SuperMen.prototype = new Humen;
SuperMen.prototype.constructor = SuperMen;
SuperMen.prototype.eat = function() {}
SuperMen.prototype.fly = function() {}
OK, 初步完成了一个“人类”和一个“超人”的基本结构了,下面让我们看下这段对“人类”的描述代码,在结构上究竟有什么不足呢?
1. SuperMen在继承的过程中出现了代码的冗余,this.xxx重复的调用了。
2. 在“超人”中,同样拥有了“人类”吃的属性,但是超人可能“吃”的具体行为和“人类”不一样。“超人”需要在拥有了“人类”吃的全部属性的同时,增加一些新的特点,比如喝喝汽油,吃吃燃料啥的。在代码中的具体表现,就是突发调动父类的方法。导致了代码会冗余。
3. 结构不够优雅(好吧,这个就见仁见智了,要是你说这样的代码很漂亮,那… … 他就很漂亮吧~)
下面让我们看下prototype.js对这段代码的重新定义
var Humen = Class.create({
initialize: function(name, age, gender) {
this.age = age;
this.name = name;
this.gender = gender;
},
eat: function() {
console.log('I eat normal food !');
},
sleep: function() {}
});
var SuperMen = Class.create(Humen, {
initialize: function($super, name, age, gender, power) {
$super(name, age, gender, power);
},
eat: function($super) {
$super();
console.log('I am ' + this.name + ', I still can eat gasoil, can you ?');
}
})
var sm = new SuperMen('supermen');
sm.eat();
结果如下:
I eat normal food ! general.js:9
I am supermen, I still can eat gasoil, can you ?
嗯,让我们现在再来做个对比,看看prototype.js中OOP的继承部分的大概结构。
prototype.js定义类的方法很简单,比起原始的js用function来定义而言,引入了Class类别。具体可以看这里。
initialize方法定义了这个类的构造函数,初始化类的基本数据。这里,值得关注的是构造方法中的第一个参数$super,如果父类中有同样的方法,$super则表示父类中同名的函数。这样一来,是不是就可以调用父类的方法了呢。而不至于造成代码的冗余。
在prototype.js的类中,有两个比较特别的参数superclasses,subclasses。分别表示了当前类的所有的子类,或者是所有的父类。这样一来,在当前的类中,我们就不不止可以操作父类中的方法,而且祖宗八倍的方法都可以调用了
是不是很棒!?
prototype.js异于jQuery的最明显的区别,就在于设计的理念不一样了,jQuery崇尚的是select and do,而在Prototype.js里,体现的更多的是一切皆是对象的思想。
prototype.js胜于jQuery的一步就在于它在定义了一些工具类方法,屏蔽了浏览器差异的同时,也为灵活的js规定了一套编程的规范,代码的规整,类的封装等等。使用这套框架的开发人员都按照这样的规则去写,代码就不至于显得太凌乱。
转载请注明出处
botobe.net
本文Github链接
2012.08.13
一切安好。
Merci !