请选择 进入手机版 | 继续访问电脑版
收藏本站腾讯微博新浪微博
点点网模板设计大赛 phpchina

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 用悬赏 三天解决问题 解决访问速度慢 论坛支持农历生日 - 给官方提建议

论坛活动及任务 归纳网站最新活动 地图任务 邮件更新任务:保护帐号安全

积分换实物,来参加蓝色理想积分兑换吧! 联系招聘客服 蓝色理想帮你找工作! 万元奖励等你拿——点点网模板设计大赛

查看: 2752|回复: 2

javascript中类的创建和继承 [复制链接]

yring 楼主
帖子
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关键字传递给新类。例如:
  1. var a = function(){   
  2.     this.a = 1;   
  3.     this.b = 2;   
  4.     alert(this);   
  5. }   
  6.   
  7. var b = function(){   
  8.     this.aa = a;//对a中的this进行转换,同样的方式还有   
  9.     this.aa();   
  10.     delete this.aa;  //要把这个中间方法删除掉,否则可能会在以后的操作中覆盖原来类的方法   
  11.   
  12.     //或者   
  13.     a.call(this,arg1,arg2);   
  14.     //或者   
  15.     a.apply(this,[args]);   
  16. }   
  17.   
  18. var ob = new b();     

  19. var a = function(){
  20.         this.a = 1;
  21.         this.b = 2;
  22.         alert(this);
  23. }

  24. var b = function(){
  25.         this.aa = a;//对a中的this进行转换,同样的方式还有
  26.         this.aa();
  27.         delete this.aa;  //要把这个中间方法删除掉,否则可能会在以后的操作中覆盖原来类的方法

  28.         //或者
  29.         a.call(this,arg1,arg2);
  30.         //或者
  31.         a.apply(this,[args]);
  32. }

  33. var ob = new b();       
复制代码


2、原型链

基本原理:关于原型链,详见(http://www.javaeye.com/topic/53537)把超类的一个实例付给子类的prototype对象,即可把超类的固定属性和方法传递给子类,要注意一点,这种方法无法在实例化时传递参数,所以一般采用混合方式进行类的继承。

prototype.js中的类定义和继承

1.6.0以前:

  1. /** obsolete syntax **/   
  2. var Person = Class.create();    //通过Class.create方法创建空类   
  3. Person.prototype = {               //把方法定义到prototype中,注意,是通过initalize方法初始化类的属性   
  4.   initialize: function(name) {   
  5.     this.name = name;   
  6.   },   
  7.   say: function(message) {   
  8.     return this.name + ': ' + message;   
  9.   }   
  10. };   
  11.   
  12. var guy = new Person('Miro');   
  13. guy.say('hi');   
  14. // -> "Miro: hi"   
  15.                                             //prototype中的继承方式:   
  16. var Pirate = Class.create();    //建立空类;   
  17. // inherit from Person class:   
  18. Pirate.prototype = Object.extend(new Person(), {    //先实例化超类,再把超类中的方法复制到子类中去,   
  19.   // redefine the speak method                               //注意,实际上prototype类定义机制中并没有直接定义   
  20. say: function(message) {                                       //类的属性而是通过intilize方法,而且所有的方法都   
  21.     return this.name + ': ' + message + ', yarr!';      //之直接定义在prototype中,所以直接用原型链方式   
  22.   }                                                                        //继承超类的所有方法不会产生问题。   
  23. });   
  24.   
  25. var john = new Pirate('Long John');   
  26. john.say('ahoy matey');   
  27. // -> "Long John: ahoy matey, yarr!"  

  28. /** obsolete syntax **/
  29. var Person = Class.create();    //通过Class.create方法创建空类
  30. Person.prototype = {               //把方法定义到prototype中,注意,是通过initalize方法初始化类的属性
  31.   initialize: function(name) {
  32.     this.name = name;
  33.   },
  34.   say: function(message) {
  35.     return this.name + ': ' + message;
  36.   }
  37. };

  38. var guy = new Person('Miro');
  39. guy.say('hi');
  40. // -> "Miro: hi"
  41.                                             //prototype中的继承方式:
  42. var Pirate = Class.create();    //建立空类;
  43. // inherit from Person class:
  44. Pirate.prototype = Object.extend(new Person(), {    //先实例化超类,再把超类中的方法复制到子类中去,
  45.   // redefine the speak method                               //注意,实际上prototype类定义机制中并没有直接定义
  46. say: function(message) {                                       //类的属性而是通过intilize方法,而且所有的方法都
  47.     return this.name + ': ' + message + ', yarr!';      //之直接定义在prototype中,所以直接用原型链方式
  48.   }                                                                        //继承超类的所有方法不会产生问题。
  49. });

  50. var john = new Pirate('Long John');
  51. john.say('ahoy matey');
  52. // -> "Long John: ahoy matey, yarr!"
复制代码


来看一下Class.create方法的实现代码
  1. var Class = {   
  2.   create: function() {   
  3.     return function() {                                          //实际上把所有的属性定义到intiliaze方法(实际上是一个类)中,   
  4.       this.initialize.apply(this, arguments);              //然后通过对象冒充方式继承该类   
  5.     }   
  6.   }   
  7. }            

  8. var Class = {
  9.   create: function() {
  10.     return function() {                                          //实际上把所有的属性定义到intiliaze方法(实际上是一个类)中,
  11.       this.initialize.apply(this, arguments);              //然后通过对象冒充方式继承该类
  12.     }
  13.   }
  14. }       
复制代码
       

可以从prototype的例子充分体会到通过对象冒充和原型链类继承的差别,一般来说属性需用对象冒充方式继承,方法需用原型链方式继承。

prototype-1.6.0以后版本:

Java代码
1.6.0以后,对prototype的类进行了更多的扩展,举例:      
  
  1. /** new, preferred syntax **/   
  2. // properties are directly passed to `create` method   
  3. var Person = Class.create({   
  4.   initialize: function(name) {                       //不必定义一个空类,and定义方法的位置改变   
  5.     this.name = name;   
  6.   },   
  7.   say: function(message) {   
  8.     return this.name + ': ' + message;   
  9.   }   
  10. });   
  11.   
  12. // when subclassing, specify the class you want to inherit from   
  13. var Pirate = Class.create(Person, {            //第一个参数是class,作为超类在定义类时直接继承   
  14.   // redefine the speak method   
  15. say: function($super, message) {   
  16.     return $super(message) + ', yarr!';   
  17.   }   
  18. });   
  19.   
  20. var john = new Pirate('Long John');   
  21. john.say('ahoy matey');   
  22. // -> "Long John: ahoy matey, yarr!"   
复制代码

  

1.6.0以后,对prototype的类进行了更多的扩展,举例:       
  1. /** new, preferred syntax **/
  2. // properties are directly passed to `create` method
  3. var Person = Class.create({
  4.   initialize: function(name) {                       //不必定义一个空类,and定义方法的位置改变
  5.     this.name = name;
  6.   },
  7.   say: function(message) {
  8.     return this.name + ': ' + message;
  9.   }
  10. });

  11. // when subclassing, specify the class you want to inherit from
  12. var Pirate = Class.create(Person, {            //第一个参数是class,作为超类在定义类时直接继承
  13.   // redefine the speak method
  14. say: function($super, message) {
  15.     return $super(message) + ', yarr!';
  16.   }
  17. });

  18. var john = new Pirate('Long John');
  19. john.say('ahoy matey');
  20. // -> "Long John: ahoy matey, yarr!"
复制代码


实现的代码比较复杂,但是基本原理和1.60以前版本差不多,也是用对象冒充继承initialize类,用原型链继承超类的方法,不过中间定义了一个klass对象,类似于工厂函数的方式
  


声明子类时对子类的initialize进行重写
1.60以前
  1. var Animal = Class.create();   
  2. Animal.prototype = {   
  3.   initialize: function(name, sound) {                                 //超类,顶一个两个参数   
  4.     this.name = name;   
  5.     this.sound = sound;   
  6.   },                 
  7.   
  8. speak: function() {   
  9. alert(name + " says: " + sound + "!");   
  10. }   
  11. };   
  12.   
  13. var snake = new Animal("Ringneck", "hissssssssss");   
  14. snake.speak();   
  15. // -> alerts "Ringneck says: hissssssssss!"   
  16.   
  17. var Dog = Class.create();   
  18.   
  19. Dog.prototype = Object.extend(new Animal(), {   
  20. initialize: function(name) { //子类,定义一个参数   
  21. this.name = name;   
  22. this.sound = "woof";   
  23. }   
  24. });   
  25.   
  26. var fido = new Dog("Fido");   
  27. fido.speak();   
  28. // -> alerts "Fido says: woof!"   

  29. var Animal = Class.create();
  30. Animal.prototype = {
  31.   initialize: function(name, sound) {                                 //超类,顶一个两个参数
  32.     this.name = name;
  33.     this.sound = sound;
  34.   },                   

  35. speak: function() {
  36. alert(name + " says: " + sound + "!");
  37. }
  38. };

  39. var snake = new Animal("Ringneck", "hissssssssss");
  40. snake.speak();
  41. // -> alerts "Ringneck says: hissssssssss!"

  42. var Dog = Class.create();

  43. Dog.prototype = Object.extend(new Animal(), {
  44. initialize: function(name) { //子类,定义一个参数
  45. this.name = name;
  46. this.sound = "woof";
  47. }
  48. });

  49. var fido = new Dog("Fido");
  50. fido.speak();
  51. // -> alerts "Fido says: woof!"
复制代码

1.60以后

  1. var Animal = Class.create({   
  2.   initialize: function(name, sound) {   
  3.     this.name = name;   
  4.     this.sound = sound;   
  5.   },   
  6.             
  7.   
  8. speak: function() {   
  9. alert(this.name + " says: " + this.sound + "!");   
  10. }   
  11. });   
  12. // subclassing Animal   
  13. var Snake = Class.create(Animal, {   
  14. initialize: function($super, name) { //通过$super的方式调用超类的initliaze,   
  15. $super(name, 'hissssssssss');   
  16. }   
  17. });   
  18. var ringneck = new Snake("Ringneck");   
  19. ringneck.speak();   
  20. //-> alerts "Ringneck says: hissssssssss!"   
  21.   
  22. var rattlesnake = new Snake("Rattler");   
  23. rattlesnake.speak();   
  24. //-> alerts "Rattler says: hissssssssss!"   
  25.   
  26. // mixing-in Enumerable   
  27. var AnimalPen = Class.create(Enumerable, {   
  28. initialize: function() {   
  29. var args = $A(arguments);   
  30. if (!args.all( function(arg) { return arg instanceof Animal }))   
  31. throw "Only animals in here!"  
  32. this.animals = args;   
  33. },   
  34.   
  35. // implement _each to use Enumerable methods   
  36. _each: function(iterator) {   
  37. return this.animals._each(iterator);   
  38. }   
  39. });   
  40. var snakePen = new AnimalPen(ringneck, rattlesnake);   
  41. snakePen.invoke('speak');   
  42. //-> alerts "Ringneck says: hissssssssss!"   
  43. //-> alerts "Rattler says: hissssssssss!"   
  44.            

  45. var Animal = Class.create({
  46.   initialize: function(name, sound) {
  47.     this.name = name;
  48.     this.sound = sound;
  49.   },
  50.              

  51. speak: function() {
  52. alert(this.name + " says: " + this.sound + "!");
  53. }
  54. });
  55. // subclassing Animal
  56. var Snake = Class.create(Animal, {
  57. initialize: function($super, name) { //通过$super的方式调用超类的initliaze,
  58. $super(name, 'hissssssssss');
  59. }
  60. });
  61. var ringneck = new Snake("Ringneck");
  62. ringneck.speak();
  63. //-> alerts "Ringneck says: hissssssssss!"

  64. var rattlesnake = new Snake("Rattler");
  65. rattlesnake.speak();
  66. //-> alerts "Rattler says: hissssssssss!"

  67. // mixing-in Enumerable
  68. var AnimalPen = Class.create(Enumerable, {
  69. initialize: function() {
  70. var args = $A(arguments);
  71. if (!args.all( function(arg) { return arg instanceof Animal }))
  72. throw "Only animals in here!"
  73. this.animals = args;
  74. },

  75. // implement _each to use Enumerable methods
  76. _each: function(iterator) {
  77. return this.animals._each(iterator);
  78. }
  79. });
  80. var snakePen = new AnimalPen(ringneck, rattlesnake);
  81. snakePen.invoke('speak');
  82. //-> alerts "Ringneck says: hissssssssss!"
  83. //-> alerts "Rattler says: hissssssssss!"
复制代码
西部数码顶级域名注册商39元抢注!
okwxj 
帖子
122
体力
788
威望
0
居住地
广东省 深圳市
发表于 2008-4-17 11:06:01 |显示全部楼层
这样的看了很多了,可不可以讲讲具体的应用?
JS
租服务器,上51IDC | [长沙]招聘:PHP经理10K/WEB前端6K/PHP开发6K

使用道具 举报

skybot 

size

钻石会员 手机认证 

帖子
3236
体力
12466
威望
7
发表于 2008-4-17 12:04:36 |显示全部楼层
JS 里没有 继承
所有的都只能是伪的
http://www.qlili.com 个人站帮点啊

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

Archiver|手机版|安久科技提供CDN|blueidea.com ( 京ICP备05002321号 )  

GMT+8, 2012-2-13 10:43 , Processed in 0.105398 second(s), 8 queries , Gzip On, Memcache On.

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部