类的定义
类定义有三种基本方法,
1、创建并能返回特定类型的对象的函数(工厂函数),例如:function Co(){ var o = new Object; o.a = 1 return o}; 用这种方式创建对象: var o = Co()
2、创建构造函数,用new 实例化,例如 function Co(){this.a = 1} 用这种方式创建对象:var o = new Co()
3、原型方式,利用对象的prototype属性,例如 function Co(){}; Co.prototype.a = 1; 用这种方式创建对象: var o = new Co()
可灵活运用这三种方式进行组合
类的继承
类的继承有两种基本方法
1、对象冒充 基本原理: 构造函数使用this关键字给所有属性和方法赋值(构造函数实际上仅仅是赋值函数),所以可以利用一种方式,在类内部直接运行赋值函数,把其this关键字传递给新类。例如:
var a = function(){ this.a = 1; this.b = 2; alert(this); } var b = function(){ this.aa = a;//对a中的this进行转换,同样的方式还有 this.aa(); delete this.aa; //要把这个中间方法删除掉,否则可能会在以后的操作中覆盖原来类的方法 //或者 a.call(this,arg1,arg2); //或者 a.apply(this,[args]); } var ob = new b(); var a = function(){ this.a = 1; this.b = 2; alert(this); } var b = function(){ this.aa = a;//对a中的this进行转换,同样的方式还有 this.aa(); delete this.aa; //要把这个中间方法删除掉,否则可能会在以后的操作中覆盖原来类的方法 //或者 a.call(this,arg1,arg2); //或者 a.apply(this,[args]); } var ob = new b();
2、原型链
基本原理:关于原型链,详见(http://www.javaeye.com/topic/53537)把超类的一个实例付给子类的prototype对象,即可把超类的固定属性和方法传递给子类,要注意一点,这种方法无法在实例化时传递参数,所以一般采用混合方式进行类的继承。
prototype.js中的类定义和继承
相关推荐:
prototype.js1.4版开发者手册
prototype-1.4.0注释版源代码下载
1.6.0以前:
/** obsolete syntax **/ var Person = Class.create(); //通过Class.create方法创建空类 Person.prototype = { //把方法定义到prototype中,注意,是通过initalize方法初始化类的属性 initialize: function(name) { this.name = name; }, say: function(message) { return this.name + ': ' + message; } }; var guy = new Person('Miro'); guy.say('hi'); // -> "Miro: hi" //prototype中的继承方式: var Pirate = Class.create(); //建立空类; // inherit from Person class: Pirate.prototype = Object.extend(new Person(), { //先实例化超类,再把超类中的方法复制到子类中去, // redefine the speak method //注意,实际上prototype类定义机制中并没有直接定义 say: function(message) { //类的属性而是通过intilize方法,而且所有的方法都 return this.name + ': ' + message + ', yarr!'; //之直接定义在prototype中,所以直接用原型链方式 } //继承超类的所有方法不会产生问题。 }); var john = new Pirate('Long John'); john.say('ahoy matey'); // -> "Long John: ahoy matey, yarr!" /** obsolete syntax **/ var Person = Class.create(); //通过Class.create方法创建空类 Person.prototype = { //把方法定义到prototype中,注意,是通过initalize方法初始化类的属性 initialize: function(name) { this.name = name; }, say: function(message) { return this.name + ': ' + message; } }; var guy = new Person('Miro'); guy.say('hi'); // -> "Miro: hi" //prototype中的继承方式: var Pirate = Class.create(); //建立空类; // inherit from Person class: Pirate.prototype = Object.extend(new Person(), { //先实例化超类,再把超类中的方法复制到子类中去, // redefine the speak method //注意,实际上prototype类定义机制中并没有直接定义 say: function(message) { //类的属性而是通过intilize方法,而且所有的方法都 return this.name + ': ' + message + ', yarr!'; //之直接定义在prototype中,所以直接用原型链方式 } //继承超类的所有方法不会产生问题。 }); var john = new Pirate('Long John'); john.say('ahoy matey'); // -> "Long John: ahoy matey, yarr!"
来看一下Class.create方法的实现代码
var Class = { create: function() { return function() { //实际上把所有的属性定义到intiliaze方法(实际上是一个类)中, this.initialize.apply(this, arguments); //然后通过对象冒充方式继承该类 } } } var Class = { create: function() { return function() { //实际上把所有的属性定义到intiliaze方法(实际上是一个类)中, this.initialize.apply(this, arguments); //然后通过对象冒充方式继承该类 } } }
可以从prototype的例子充分体会到通过对象冒充和原型链类继承的差别,一般来说属性需用对象冒充方式继承,方法需用原型链方式继承。
prototype-1.6.0以后版本:
Java代码
1.6.0以后,对prototype的类进行了更多的扩展,举例:
/** new, preferred syntax **/ // properties are directly passed to `create` method var Person = Class.create({ initialize: function(name) { //不必定义一个空类,and定义方法的位置改变 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, { //第一个参数是class,作为超类在定义类时直接继承 // 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!"
1.6.0以后,对prototype的类进行了更多的扩展,举例:
/** new, preferred syntax **/ // properties are directly passed to `create` method var Person = Class.create({ initialize: function(name) { //不必定义一个空类,and定义方法的位置改变 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, { //第一个参数是class,作为超类在定义类时直接继承 // 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!"
实现的代码比较复杂,但是基本原理和1.60以前版本差不多,也是用对象冒充继承initialize类,用原型链继承超类的方法,不过中间定义了一个klass对象,类似于工厂函数的方式
声明子类时对子类的initialize进行重写
1.60以前
var Animal = Class.create(); Animal.prototype = { initialize: function(name, sound) { //超类,顶一个两个参数 this.name = name; this.sound = sound; }, speak: function() { alert(name + " says: " + sound + "!"); } }; var snake = new Animal("Ringneck", "hissssssssss"); snake.speak(); // -> alerts "Ringneck says: hissssssssss!" var Dog = Class.create(); Dog.prototype = Object.extend(new Animal(), { initialize: function(name) { //子类,定义一个参数 this.name = name; this.sound = "woof"; } }); var fido = new Dog("Fido"); fido.speak(); // -> alerts "Fido says: woof!" var Animal = Class.create(); Animal.prototype = { initialize: function(name, sound) { //超类,顶一个两个参数 this.name = name; this.sound = sound; }, speak: function() { alert(name + " says: " + sound + "!"); } }; var snake = new Animal("Ringneck", "hissssssssss"); snake.speak(); // -> alerts "Ringneck says: hissssssssss!" var Dog = Class.create(); Dog.prototype = Object.extend(new Animal(), { initialize: function(name) { //子类,定义一个参数 this.name = name; this.sound = "woof"; } }); var fido = new Dog("Fido"); fido.speak(); // -> alerts "Fido says: woof!"
1.60以后
var Animal = Class.create({ initialize: function(name, sound) { this.name = name; this.sound = sound; }, speak: function() { alert(this.name + " says: " + this.sound + "!"); } }); // subclassing Animal var Snake = Class.create(Animal, { initialize: function($super, name) { //通过$super的方式调用超类的initliaze, $super(name, 'hissssssssss'); } }); var ringneck = new Snake("Ringneck"); ringneck.speak(); //-> alerts "Ringneck says: hissssssssss!" var rattlesnake = new Snake("Rattler"); rattlesnake.speak(); //-> alerts "Rattler says: hissssssssss!" // mixing-in Enumerable var AnimalPen = Class.create(Enumerable, { initialize: function() { var args = $A(arguments); if (!args.all( function(arg) { return arg instanceof Animal })) throw "Only animals in here!" this.animals = args; }, // implement _each to use Enumerable methods _each: function(iterator) { return this.animals._each(iterator); } }); var snakePen = new AnimalPen(ringneck, rattlesnake); snakePen.invoke('speak'); //-> alerts "Ringneck says: hissssssssss!" //-> alerts "Rattler says: hissssssssss!" var Animal = Class.create({ initialize: function(name, sound) { this.name = name; this.sound = sound; }, speak: function() { alert(this.name + " says: " + this.sound + "!"); } }); // subclassing Animal var Snake = Class.create(Animal, { initialize: function($super, name) { //通过$super的方式调用超类的initliaze, $super(name, 'hissssssssss'); } }); var ringneck = new Snake("Ringneck"); ringneck.speak(); //-> alerts "Ringneck says: hissssssssss!" var rattlesnake = new Snake("Rattler"); rattlesnake.speak(); //-> alerts "Rattler says: hissssssssss!" // mixing-in Enumerable var AnimalPen = Class.create(Enumerable, { initialize: function() { var args = $A(arguments); if (!args.all( function(arg) { return arg instanceof Animal })) throw "Only animals in here!" this.animals = args; }, // implement _each to use Enumerable methods _each: function(iterator) { return this.animals._each(iterator); } }); var snakePen = new AnimalPen(ringneck, rattlesnake); snakePen.invoke('speak'); //-> alerts "Ringneck says: hissssssssss!" //-> alerts "Rattler says: hissssssssss!"
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/webwalker/archive/2008/02/18/2102333.aspx