Skip to content

Instantly share code, notes, and snippets.

@s-hiiragi
Created October 20, 2013 07:55
Show Gist options
  • Save s-hiiragi/7066214 to your computer and use it in GitHub Desktop.
Save s-hiiragi/7066214 to your computer and use it in GitHub Desktop.
クラスベースオブジェクト指向 on JavaScript
console.log( 'クラスベースオブジェクト指向 on JavaScript' );
console.group( 'Functionを使う方法' );
(function() {
console.group( '(1) A, B, Cクラス兼コンストラクタとクラスメソッドを定義' );
console.log( 'CはBを継承, BはAを継承する' );
function A() { /* 初期化処理 */ }
A.intro = function() { console.log('A'); };
function B() { /* 初期化処理 */ }
function C() { /* 初期化処理 */ }
C.intro = function() { console.log('C'); };
console.log('A', A);
console.log('B', B);
console.log('C', C);
console.groupEnd();
console.group( '(2) A, B, Cクラスのインスタンスメソッド(prototype)を定義' );
// 以下の2行は勝手に行われるため不要
//A.prototype = {};
//A.prototype.constructor = A;
B.prototype = new A();
B.prototype.constructor = B;
C.prototype = new B();
C.prototype.constructor = C;
A.prototype.intro = function() { console.log('A.prototype'); };
C.prototype.intro = function() { console.log('C.prototype'); };
console.log('A.prototype', A.prototype);
console.log('B.prototype', B.prototype);
console.log('C.prototype', C.prototype);
console.groupEnd();
console.group( '(3) A, B, Cクラスのインスタンスを生成' );
var a = new A(); // A.create()でもOK
var b = new B(); // B.create()でもOK
var c = new C(); // C.create()でもOK
console.log('a', a);
console.log('b', b);
console.log('c', c);
console.groupEnd();
console.group( '(4) クラスメソッドの継承、オーバーライド' );
console.log( '=> 不可能' );
console.groupEnd();
console.group( '(5) インスタンスメソッドの継承、オーバーライド' );
a.intro(); //=> A.prototype
b.intro(); //=> B.prototype, 継承
c.intro(); //=> C.prototype, オーバーライド
console.groupEnd();
console.group( '(6) クラスの継承関係を調べる' );
console.log( '=> 不可能' );
console.groupEnd();
console.group( '(7) インスタンスの継承関係を調べる' );
console.log( 'a instanceof A', a instanceof A ); //=> true
console.log( 'a instanceof B', a instanceof B ); //=> false
console.log( 'a instanceof C', a instanceof C ); //=> false
console.log( 'b instanceof A', b instanceof A ); //=> true
console.log( 'b instanceof B', b instanceof B ); //=> true
console.log( 'b instanceof C', b instanceof C ); //=> false
console.log( 'c instanceof A', c instanceof A ); //=> true
console.log( 'c instanceof A', c instanceof B ); //=> true
console.log( 'c instanceof A', c instanceof C ); //=> true
console.groupEnd();
console.group( '(8) プロトタイプチェーンを辿る (ES5 以降で可能)' );
console.log( 'Object.getPrototypeOf(C.prototype) === B.prototype', Object.getPrototypeOf(C.prototype) === B.prototype ); //=> true
console.log( 'Object.getPrototypeOf(B.prototype) === A.prototype', Object.getPrototypeOf(B.prototype) === A.prototype ); //=> true
console.groupEnd();
console.group( '(9) インスタンスからクラスを取得する' );
console.log( 'a.constructor === A', a.constructor === A ); //=> true
console.log( 'b.constructor === B', b.constructor === B ); //=> true
console.log( 'c.constructor === C', c.constructor === C ); //=> true
console.groupEnd();
console.group( '(10) クラスからprototypeを取得する' );
console.log( 'A.prototype', A.prototype );
console.log( 'B.prototype', B.prototype );
console.log( 'C.prototype', C.prototype );
console.groupEnd();
console.group( '(11) インスタンスからprototypeを取得する (ES5 以降で可能)' );
console.log( 'Object.getPrototypeOf(a) === A.prototype', Object.getPrototypeOf(a) === A.prototype ); //=> true
console.log( 'Object.getPrototypeOf(b) === B.prototype', Object.getPrototypeOf(b) === B.prototype ); //=> true
console.log( 'Object.getPrototypeOf(c) === C.prototype', Object.getPrototypeOf(c) === C.prototype ); //=> true
console.groupEnd();
})();
console.groupEnd();
console.group( 'Object.createを使う方法' );
(function() {
console.group( '(1) A, B, Cクラス兼コンストラクタとクラスメソッドを定義' );
console.log( 'CはBを継承, BはAを継承する' );
// (1) A, B, Cクラスとクラスメソッドを定義
var A = Object.create({});
A.create = function() { return Object.create(A.prototype); /* 初期化処理 */ };
A.intro = function() { console.log('A'); };
var B = Object.create(A);
B.create = function() { return Object.create(B.prototype); /* 初期化処理 */ };
var C = Object.create(B);
C.create = function() { return Object.create(C.prototype); /* 初期化処理 */ };
C.intro = function() { console.log('C'); };
console.log('A', A);
console.log('B', B);
console.log('C', C);
console.groupEnd();
console.group( '(2) A, B, Cクラスのインスタンスメソッド(prototype)を定義' );
A.prototype = Object.create({});
A.prototype.constructor = A;
B.prototype = Object.create(A.prototype); // TODO A.create() にすべきか検討中
B.prototype.constructor = B;
C.prototype = Object.create(B.prototype); // TODO B.create() にすべきか検討中
C.prototype.constructor = C;
A.prototype.intro = function() { console.log('A.prototype'); };
C.prototype.intro = function() { console.log('C.prototype'); };
console.log('A.prototype', A.prototype);
console.log('B.prototype', B.prototype);
console.log('C.prototype', C.prototype);
console.groupEnd();
console.group( '(3) A, B, Cクラスのインスタンスを生成' );
var a = A.create();
var b = B.create();
var c = C.create();
console.dir('a', a);
console.dir('b', b);
console.dir('c', c);
console.groupEnd();
console.group( '(4) クラスメソッドの継承、オーバーライド' );
A.intro(); //=> A
B.intro(); //=> A, 継承
C.intro(); //=> C, オーバーライド
console.groupEnd();
console.group( '(5) インスタンスメソッドの継承、オーバーライド' );
a.intro(); //=> A.prototype
b.intro(); //=> A.prototype, 継承
c.intro(); //=> C.prototype, オーバーライド
console.groupEnd();
console.group( '(6) クラスの継承関係を調べる' );
console.log( 'Object.getprototypeOf(C) === B', Object.getPrototypeOf(C) === B ); //=> true
console.log( 'Object.getprototypeOf(B) === A', Object.getPrototypeOf(B) === A ); //=> true
console.groupEnd();
console.group( '(7) インスタンスの継承関係を調べる');
console.log( 'instanceof演算子の代わりにObject#isPrototypeOf()を使う' );
console.log( 'A.prototype.isPrototypeOf(a)', A.prototype.isPrototypeOf(a) ); //=> true
console.log( 'B.prototype.isPrototypeOf(a)', B.prototype.isPrototypeOf(a) ); //=> false
console.log( 'C.prototype.isPrototypeOf(a)', C.prototype.isPrototypeOf(a) ); //=> false
console.log( 'A.prototype.isPrototypeOf(b)', A.prototype.isPrototypeOf(b) ); //=> true
console.log( 'B.prototype.isPrototypeOf(b)', B.prototype.isPrototypeOf(b) ); //=> true
console.log( 'C.prototype.isPrototypeOf(b)', C.prototype.isPrototypeOf(b) ); //=> false
console.log( 'A.prototype.isPrototypeOf(c)', A.prototype.isPrototypeOf(c) ); //=> true
console.log( 'B.prototype.isPrototypeOf(c)', B.prototype.isPrototypeOf(c) ); //=> true
console.log( 'C.prototype.isPrototypeOf(c)', C.prototype.isPrototypeOf(c) ); //=> true
console.groupEnd();
console.group( '(8) プロトタイプチェーンを辿る (方法1と同一)' );
console.log( 'Object.getPrototypeOf(C.prototype) === B.prototype', Object.getPrototypeOf(C.prototype) === B.prototype ); //=> true
console.log( 'Object.getPrototypeOf(B.prototype) === A.prototype', Object.getPrototypeOf(B.prototype) === A.prototype ); //=> true
console.groupEnd();
console.group( '(9) インスタンスからクラスを取得する (方法1と同一)' );
console.log( 'a.constructor === A', a.constructor === A ); //=> true
console.log( 'b.constructor === B', b.constructor === B ); //=> true
console.log( 'c.constructor === C', c.constructor === C ); //=> true
console.groupEnd();
console.group( '(10) クラスからprototypeを取得する (方法1と同一)' );
console.log( 'A.prototype', A.prototype );
console.log( 'B.prototype', B.prototype );
console.log( 'C.prototype', C.prototype );
console.groupEnd();
console.group( '(11) インスタンスからprototypeを取得する (方法1と同一)' );
console.log( 'Object.getPrototypeOf(a) === A.prototype', Object.getPrototypeOf(a) === A.prototype ); //=> true
console.log( 'Object.getPrototypeOf(b) === B.prototype', Object.getPrototypeOf(b) === B.prototype ); //=> true
console.log( 'Object.getPrototypeOf(c) === C.prototype', Object.getPrototypeOf(c) === C.prototype ); //=> true
console.groupEnd();
})();
console.groupEnd();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment