JavaScript中對象繼承

來源:互聯網
上載者:User

類的繼承有兩種基本方法

對象冒充 基本原理: 建構函式使用this關鍵字給所有屬性和方法賦值(建構函式實際上僅僅是賦值函數),所以可以利用一種方式,在類內部直接運行賦值函數,把其this關鍵字傳遞給新類。例如:

Java代碼

   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();    

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();   

原型鏈

基本原理:關於原型鏈,詳見(http://www.javaeye.com/topic/53537)把超類的一個執行個體付給子類的prototype對象,即可把超類的固定屬性和方法傳遞給子類,要注意一點,這種方法無法在執行個體化時傳遞參數,所以一般採用混合方式進行類的繼承。

prototype.js中的類定義和繼承

1.6.0以前:

Java代碼

   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!" 

/** 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方法的實現代碼

Java代碼

   1. var Class = { 
   2.   create: function() { 
   3.     return function() {                                          //實際上把所有的屬性定義到intiliaze方法(實際上是一個類)中, 
   4.       this.initialize.apply(this, arguments);              //然後通過對象冒充方式繼承該類 
   5.     } 
   6.   } 
   7. }            

var Class = {
  create: function() {
    return function() {                                          //實際上把所有的屬性定義到intiliaze方法(實際上是一個類)中,
      this.initialize.apply(this, arguments);              //然後通過對象冒充方式繼承該類
    }
  }
}           

可以從prototype的例子充分體會到通過對象冒充和原型鏈類繼承的差別,一般來說屬性需用對象冒充方式繼承,方法需用原型鏈方式繼承。

prototype-1.6.0以後版本:

Java代碼

   1. 1.6.0以後,對prototype的類進行了更多的擴充,舉例:     
   2.  
   3. /** new, preferred syntax **/  
   4. // properties are directly passed to `create` method  
   5. var Person = Class.create({  
   6.   initialize: function(name) {                       //不必定義一個空類,and定義方法的位置改變 
   7.     this.name = name;  
   8.   },  
   9.   say: function(message) {  
  10.     return this.name + ': ' + message;  
  11.   }  
  12. });  
  13.  
  14. // when subclassing, specify the class you want to inherit from  
  15. var Pirate = Class.create(Person, {            //第一個參數是class,作為超類在定義類時直接繼承 
  16.   // redefine the speak method  
  17. say: function($super, message) {  
  18.     return $super(message) + ', yarr!';  
  19.   }  
  20. });  
  21.  
  22. var john = new Pirate('Long John');  
  23. john.say('ahoy matey');  
  24. // -> "Long John: ahoy matey, yarr!" 
  25.  
  26.  
  27.  
  28. //聲明子類時對子類的initialize進行重寫 

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!"

//聲明子類時對子類的initialize進行重寫

1.60以前

Java代碼

   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!"   

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以後

Java代碼

   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!"

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!"

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.