在较早版本的Prototype框架中,创建类的基本方法是调用Class.create()函数.通过这种方法创建的类,他的构造函数回自动调用initialize方法.从Prototype1.6.0开始,Class模块开始支持继承,相比老版本有较大改进,现在创建新类的时候将更加方便。 在Prototype中创建类的基本方法仍然是Class.create()函数。在新版本中,以前的代码仍能支持;但是现在,我们可以不用直接对JavaScript对象的prototypes 进行修改或者使用Object.extend()来复制所有属性。 例子 先让我们看一下早版本中Prototype中的类的定义和继承。
这里我们可以看到继承是通过修改类的prototype,并且调用Object.extend函数。同时,Pirate重写了Persion的say()方法,我们没有办法向在编程语言中那样使用基类的方法。 在新版本中都做了改进,下面的代码是使用新版,相比上面的代码,将更简洁。
现在基类和子类的定义都更简洁,因为我们不再需要直接修改对象的prototype。同时还有一个新特性,就是增加了$super关键字,支持对基类方法的调用。 如何组合模块 现在已经知道通常创建类的方法是调用Calss.create()函数.
但实际上,Class.create函数可以接收任意数量的参数。第一个参数,如果是一个另外定义的类,那么新创建的类将继承它。另外所有的参数都会作为实例方法增加到新创建的类中。这样可以方便的组合已有各个模块。
上例中Vulnerable不是一个类,但是新定义的Person类仍然包含了所有Vulnerable的方法和属性。Prototype的这个特性,使我们很容易地组合各个模块,提高代码重用率。 方法定义中的$super参数 当我们在子类中重写一个方法,并希望调用基类的方法,那么需要一个指向基类方法的引用。现在可以通过传入一个附加参数$super来指向基类的方法($super参数必须作为第一个参数)。但是外部调用的时候,不必需要知道这个$super参数,如上例中,调用Pirate的say方法时,仍然只需要传入一个参数。
/** obsolete syntax **/
var Person = Class.create();
Person.prototype = {
initialize: function(name) {
this.name = name;
},
say: function(message) {
return this.name + ': ' + message;
}
};
var guy = new Person('Miro');
guy.say('hi');
// -> "Miro: hi"
var Pirate = Class.create();
// inherit from Person class:
Pirate.prototype = Object.extend(new Person(), {
// redefine the speak method
say: function(message) {
return this.name + ': ' + message + ', yarr!';
}
});
var john = new Pirate('Long John');
john.say('ahoy matey');
// -> "Long John: ahoy matey, yarr!"
这里我们可以看到继承是通过修改类的prototype,并且调用Object.extend函数。同时,Pirate重写了Persion的say()方法,我们没有办法向在编程语言中那样使用基类的方法。 在新版本中都做了改进,下面的代码是使用新版,相比上面的代码,将更简洁。
/** new, preferred syntax **/
// properties are directly passed to `create` method
var Person = Class.create({
initialize: function(name) {
this.name = name;
},
say: function(message) {
return this.name + ': ' + message;
}
});
// when subclassing, specify the class you want to inherit from
var Pirate = Class.create(Person, {
// redefine the speak method
say: function($super, message) {
return $super(message) + ', yarr!';
}
});
var john = new Pirate('Long John');
john.say('ahoy matey');
// -> "Long John: ahoy matey, yarr!"
现在基类和子类的定义都更简洁,因为我们不再需要直接修改对象的prototype。同时还有一个新特性,就是增加了$super关键字,支持对基类方法的调用。 如何组合模块 现在已经知道通常创建类的方法是调用Calss.create()函数.
var Pirate = Class.create(Person, { /* instance methods */ });
但实际上,Class.create函数可以接收任意数量的参数。第一个参数,如果是一个另外定义的类,那么新创建的类将继承它。另外所有的参数都会作为实例方法增加到新创建的类中。这样可以方便的组合已有各个模块。
// define a module
var Vulnerable = {
wound: function(hp) {
this.health -= hp;
if (this.health < 0) this.kill();
},
kill: function() {
this.dead = true;
}
};
// the first argument isn't a class object, so there is no inheritance ...
// simply mix in all the arguments as methods:
var Person = Class.create(Vulnerable, {
initialize: function() {
this.health = 100;
this.dead = false;
}
});
var bruce = new Person;
bruce.wound(55);
bruce.health; //-> 45
上例中Vulnerable不是一个类,但是新定义的Person类仍然包含了所有Vulnerable的方法和属性。Prototype的这个特性,使我们很容易地组合各个模块,提高代码重用率。 方法定义中的$super参数 当我们在子类中重写一个方法,并希望调用基类的方法,那么需要一个指向基类方法的引用。现在可以通过传入一个附加参数$super来指向基类的方法($super参数必须作为第一个参数)。但是外部调用的时候,不必需要知道这个$super参数,如上例中,调用Pirate的say方法时,仍然只需要传入一个参数。
没有评论:
发表评论