- 在线时间
- 69 小时
- 专家
- 0
- UID
- 276739
- 注册时间
- 2006-7-17
- 帖子
- 31
- 精华
- 0
- 积分
- 75
- 离线
- 1396 天
- 帖子
- 31
- 体力
- 75
- 威望
- 0
|
发表于 2008-3-18 11:05:06
|显示全部楼层
类的定义
类定义有三种基本方法,
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中的类定义和继承
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!"
复制代码 |
|