Prototype 1.6的类继承
原来的Prototype支持Class,大概就是下面这样
Code
var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
},
.
}
var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
},
.
}
调用时候new PeriodicalExecuter(...)其实就是调用initialize构造方法,不能实现类的继承,1.6当中改进了Class的构造,大概介绍一下
首先,create可以传参数了Class.create(parent,methods),parent可以是匿名对象或者类,methods就是子类方法,示例:
代码
- var test=Class.create({a:123,b:456,c:[1,2,3],initialize:function(){}})
- var result=new test;
就可以取代原来的
代码
- var test=Class.create();
- test.prototype={
- a:123,
- b:456,
- c:[1,2,3],
- initialize:function(){}
- }
这样了,这还不是重点,下面讲继承
代码
- var a=Class.create({initialize:function(){},test1:123,test2:456,check:function(){alert(this.test1)}})
- var b=Class.create(a,{check:function(){alert(this.test2)}})
- c=new b;
- c.check()
当然显示456了,因为子类覆盖父类同名方法,但是如果你还想调用父类方法呢,那好办,Prototype定义了$super关键字,但是必须作为子类方法第一个参数,就是
代码
- var a=Class.create({initialize:function(){},test1:123,test2:456,check:function(){alert(this.test1)}})
- var b=Class.create(a,{check:function($super){alert(this.test2);$super()}})
至此,Prototype完成了对js的Class扩展任务
加入了mixin方法和类的addMethods方法,比如现在可以
代码
- var a=Class.create({a;1,b:2},{c:3,d:4},......)
这些都可以被加入到类里面,当然没有继承,如果重名,后面覆盖前面,再有addMethods
比如
代码
- a=Class.create({a:1,b:2,initialize:function(){}})
- b=new a
- a.addMethods({
- test:function(){alert(123)},
- test2:function(){alert(456)}
- })
- b.test()
- b.test2()
基本相当于a.prototype扩展,但是不完全
代码
- a=Class.create({a:1,b:2,initialize:function(){},test:function(){alert(this.a)}})
- b=Class.create(a,{})
- b.addMethods({test:function($super){alert(this.b);$super()}})
可以支持$super的继承
参考资料:
http://prototypejs.org/learn/class-inheritance
creation.js
var Animal = Class.create({
initialize : function(name) {
this.name = name;
},
eat : function(food) {
this.say('Yum!');
},
say : function(msg) {
document.write(this.name + ': ' + msg + "<br />");
}
});
var Animal = Class.create({
initialize : function(name) {
this.name = name;
},
eat : function(food) {
this.say('Yum!');
},
say : function(msg) {
document.write(this.name + ': ' + msg + "<br />");
}
});
extend.js
var Cat = Class.create(Animal, {
initialize : function($super, name) {
this.name = "extend" + name;
$super(name);
},
eat : function($super, food) {
if(food instanceof Mouse) return $super(food);
return this.say('Yuck! I only eat mice.');
}
});
var Mouse = Class.create(Animal);
var fido = new Animal('Fido');
var tom = new Cat('Tom');
var jerry = new Mouse('Jerry');
tom.say('Hi');
jerry.eat('cheese');
tom.eat('bone');
tom.eat(fido);
tom.eat(jerry);
var Cat = Class.create(Animal, {
initialize : function($super, name) {
this.name = "extend" + name;
$super(name);
},
eat : function($super, food) {
if(food instanceof Mouse) return $super(food);
return this.say('Yuck! I only eat mice.');
}
});
var Mouse = Class.create(Animal);
var fido = new Animal('Fido');
var tom = new Cat('Tom');
var jerry = new Mouse('Jerry');
tom.say('Hi');
jerry.eat('cheese');
tom.eat('bone');
tom.eat(fido);
tom.eat(jerry);