2011-07-07 24 views
24

私は次のコードスニペットを持っているとしましょう。親コンストラクタを呼び出す方法は?

function test(id) { alert(id); } 

testChild.prototype = new test(); 

function testChild(){} 

var instance = new testChild('hi'); 

alert('hi')は入手できますか?私は今undefinedを得ます。

答えて

6

class Test 
    constructor: (id) -> alert(id) 

class TestChild extends Test 

instance = new TestChild('hi') 

いや、私は聖戦を開始いませんよ。その代わり、私は、サブクラス化を実装することができるか見るためにJavaScriptコードをその結果を見てみることを示唆しています:

// Function that does subclassing 
var __extends = function(child, parent) { 
    for (var key in parent) { 
    if (Object.prototype.hasOwnProperty.call(parent, key)) { 
     child[key] = parent[key]; 
    } 
    } 
    function ctor() { this.constructor = child; } 
    ctor.prototype = parent.prototype; 
    child.prototype = new ctor; 
    child.__super__ = parent.prototype; 
    return child; 
}; 

// Our code 
var Test, TestChild, instance; 

Test = function(id) { alert(id); }; 

TestChild = function() { 
    TestChild.__super__.constructor.apply(this, arguments); 
}; __extends(TestChild, Test); 

instance = new TestChild('hi'); 

// And we get an alert 

http://jsfiddle.net/NGLMW/3/でアクションでそれを参照してください。

正しいままにするために、CoffeeScriptの出力と比較して、コードを少し変更して読みやすくするようコメントしました。

+0

良い分析とjsFiddleの例については+1 – JCotton

0

プロトタイプを設定する前にfunction testChild()を宣言する必要があります。次に、メソッドを呼び出すにはtestChild.testに電話する必要があります。 testChild.prototype.test = testを設定したいとお考えの場合は、testChild.test('hi')に電話すると正しく解決されます。あなたはのCoffeeScriptでこれを行う方法です

+0

.. – Moon

+0

は//はい...私は手動でテストを呼び出すことができますが、私は何をしたいコールテストは()私たちは、他のOOP言語でできるようにそれを起動せずにです。 – Moon

3

variable argumentsapply()メソッドを利用することで、このようにすることができます。この例ではfiddleです。

function test(id) { alert(id); } 
function testChild() { 
    testChild.prototype.apply(this, arguments); 
    alert('also doing my own stuff'); 
} 
testChild.prototype = test; 
var instance = new testChild('hi', 'unused', 'optional', 'args'); 
+0

これはおそらく、よく定義された言語標準を利用する最もクロスブラウザのソリューションです。 –

+0

これはおそらく 'this .__ proto __。apply(this、arguments)'と書き直すことができるので、より一般的で再利用可能です。また、 'testChild.prototype = Object.create(test.prototype);のように' Object.create'を使って継承を定義した場合、これはうまくいかないことに注意してください;これは野生で継承を作成するためにかなり受け入れられているようです。 –

98

JS OOP ...

// parent class 
var Test = function(id) { 
    console.log(id); 
}; 

// child class 
var TestChild = function(id) { 
    Test.call(this, id); // call parent constructor 
}; 

// extend from parent class prototype 
TestChild.prototype = Object.create(Test.prototype); // keeps the proto clean 
TestChild.prototype.constructor = TestChild; // repair the inherited constructor 

// end-use 
var instance = new TestChild('foo'); 
+1

ありがとう、確かにJSでこれを行う方法:P –

+0

あなたはこのようにしてプロトタイプのチェーンを台無しになる。これを行う方法は実際にはhttp://js-bits.blogspot.com.au/2010/08/javascript-inheritance-done-right.htmlのようになります – papercowboy

+0

@cayuuこれはどのようにしてプロトタイプチェーンを台無しにしますか? – roylaurie

14

あなたはすでに多くの答えを持っているが、私は私見これを行うための新しい標準的な方法ですES6の方法、でスローされます。 //それでも動作しない

class Parent { 
    constructor() { alert('hi'); } 
} 
class Child extends Parent { 
    // Optionally include a constructor definition here. Leaving it 
    // out means the parent constructor is automatically invoked. 
    constructor() { 
    // imagine doing some custom stuff for this derived class 
    super(); // explicitly call parent constructor. 
    } 
} 

// Instantiate one: 
var foo = new Child(); // alert: hi 
+0

良い点。残念ながら、 'super()'はIE11(http://kangax.github.io/compat-table/es6/)でもサポートされていません。これは生産的な環境で問題になる可能性があります。 – BurninLeo

+0

良いリマインダーいつものように、可能であれば、この問題やその他の非互換性のために、ソースをES5に移すことをお勧めします。 Webpack、Typescriptなどのツールを使用してこれを行うことができます。 – Sk606

関連する問題