javascriptにおけるクラスの定義と継承


クラスの定義
クラス定義には三つの基本的な方法があります.
特定のタイプのオブジェクトの関数(工場関数)を作成して返します.例えば、function Co(){var o=new Object;o.a=1 returno];このようにオブジェクトを作成します.var o=Co()
コンストラクタを作成し、newを用いて具体化します.例えば、function Co(){this.a=1}はこのようにオブジェクトを作成します.var o=new Co()
プロトタイプ方式は、オブジェクトのプロトタイプ属性、例えば、function Co(){}を利用する.Co.prototype.a=1このようにオブジェクトを作成します.var o=new Co()
この3つの方法を活用して組み合わせができます.
クラスの継承
クラスの継承には二つの基本的な方法があります.
基本原理としては、オブジェクトを偽る:構造関数は、すべての属性と方法に対して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();	
原型チェーン
基本原理:プロトタイプチェーンについて、詳しくは(http://www.iteye.com/topic/53537)超クラスの一例をサブクラスのプロトタイプオブジェクトに割り当てると、超クラスの固定属性と方法をサブクラスに渡すことができます.この方法は、インスタンス化時にパラメータを渡すことができないので、一般的には混合方式でクラスを継承します.
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!"
Class.reat方法の実現コードを見てください.
var Class = {
  create: function() {
    return function() {                                          //            intiliaze  (       ) ,
      this.initialize.apply(this, arguments);              //              
    }
  }
}			
プロトタイプの例から、オブジェクトの偽名とプロトタイプチェーンの継承の違いを十分に実感することができます.一般的には属性は対象と偽って継承する必要があり、方法はプロトタイプチェーンで継承する必要があります.
prototype-1.6.0以降のバージョン:
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以前
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!"