2017-10-19 3 views
1

現在、javascriptのプロトタイプを使用してクラス継承を作成しようとしていますが、下の簡単な例でその動作を理解しています。親コンストラクタパラメータを使用したJavascript継承

var Person = function(){ 
    var name = "Steve"; 
} 

var Employee = function(){ 
    var company = "Stack Overflow"; 
} 

Employee.prototype = new Person; 

var employee1 = new Employee(); 

ここで、オブジェクトを作成するときに値を設定できるように、コンストラクタにパラメータを追加したいとします。したがって、更新されたコードは次のようになります。

var Person = function(initName){ 
    var name = initName; 
} 

var Employee = function(initName, initCompany){ 
    //How can I use initName to set the value in the prototype class? 

    var company = initCompany; 
} 

Employee.prototype = new Person; 

var employee1 = new Employee("Bob", "Intel"); 

Personコンストラクタをどのように呼び出すことができますか?私が最も心地よい言語であるC#では、単純に基本コンストラクタを呼び出して必要なパラメータを渡しますが、javascriptに相当するパターンはないようです。

参考のために、これはC#でどのように見えるかです:

public class Person 
{ 
    string name; 

    public Person(string initName) 
    { 
     name = initName; 
    } 
} 

public class Employee : Person 
{ 
    string company; 

    public Employee(string initName, string initCompany) : base(initName) 
    { 
     company = initCompany; 
    } 
} 

var employee1 = new Employee("Bob", "Intel"); 

免責事項:あなたが見ることができるように、私は主にオブジェクト指向プログラマが、私は現在、JavaScriptで作業し、そのいくつかしています私が尋ねたことは、javascriptの観点からは非センシティブかもしれませんが、必要に応じて私の前提条件に自由に挑戦してください。

+0

このクエストを参照してください[ここにリンクの説明を入力してください](https://stackoverflow.com/questions/4152931/javascript-inheritance-call-super-constructor-or-use-prototype-chain)ion。それはあなたが探しているすべてを持っています –

+0

これを参照してください[回答](https://stackoverflow.com/questions/4152931/javascript-inheritance-call-super-constructor-or-use-prototype-chain)。それはあなたが探しているすべてを持っています。 –

答えて

1

標準ES5として、あなたの例の特定の場合については

の下にこれを書くことができ、headmax's answerは何が必要ありません。しかし、C#や他の言語で古典的な継承モデルを使用すると、一般的な意味で(つまり古典的な継承)実行しようとしていることが可能ですが、JavaScriptプロトタイプモデルでは同じことはできません。あなたは、おそらくそうのように、組成物を用いたものに最も近いを取得することができます:

var Person = function(initName){ 
    var name = initName; 
} 

var Employee = function(initName, initCompany){ 
    var innerPerson = new Person(initName); 

    var company = initCompany; 
} 

var employee1 = new Employee("Bob", "Intel"); 

その後、任意の追加機能は、あなたがパススルーとして実装されなければならないPersonクラスを拡張ミラーまたはEmployeeクラスに実装したいと思います、すなわち、内部のPersonオブジェクト内の対応する関数を呼び出します。確かに、これは実際の継承とはかけ離れていますが、多型性などのために動作を近似することができます。

EDIT

まあこれは私が完全に前に忘れものですが、あなたは実際にcall()またはapply()を使用して、継承の行動の少しより多くを達成することができます。あなたはこのように、子のコンテキストで親のコンストラクタを実行できるように呼び出しを使用または適用するとは、指定されたコンテキストで(オブジェクトのコンストラクタを含む)機能を実行することができます:

var Person = function(initName){ 
    var name = initName; 
} 

var Employee = function(initName, initCompany){ 
    Person.call(this, initName); 
    var innerPerson = new Person(initName); 

    var company = initCompany; 
} 

var employee1 = new Employee("Bob", "Intel"); 

しかし、あなたがしたい場合Employeeコンストラクタ内のnameプロパティとEmployee内で定義する他の関数にアクセスできるようにするには、名前のスコープの可視性をvar name = ...からthis.name = ...に変更する必要があります。これにより、オブジェクトのスコープ内に表示されますthisは、コンストラクタ関数の範囲にバインドされているのとは対照的に)。使用中のこのすべての素晴らしい例については、hereを参照してください。ECMAScriptの2015年の採用によりES6

は、あなたが今より古典的な継承のようにたくさん見える糖衣構文であなたのクラス定義をラップすることができます。しかし、これはフードのプロトタイプの継承で実装されていることを覚えておく必要があります。call()/apply()が実際に実行されたときにコードが実行されたり、Babelのようなトランスペラレータが書き換えられます。

+0

私がやりたいことをやり遂げることができないかもしれない、コンポジションを使用する代わりのアプローチに感謝します。私は誰かがラインの下でより良い答えを出さない限り、今のところそれに行かなければならないでしょう。彼らがそうでなければ、私はあなたのものを明日受け入れられるものとしてマークします。 –

+0

嬉しい構成が助けになるかもしれませんが、役に立つとより多くの相続のようないくつかの他の方法を含む答えを更新しました –

+0

優秀! Person.callを使い、 "var innerPerson"行を削除し、スコープを "var ..."ではなく "this ..."に変更すると、他の方法よりも私が望むものにもっと近づきます。基本的にすべての動作をカバーしています(特に、子クラスで必要に応じて関数やプロパティを上書きできるため) –

1

JavaScriptにはES6以降の実際のクラスがあります。彼らは古いブラウザ(つまり、Internet Explorerなど)で動作しませんが、あなたは

class Person { 
    constructor(name){ 
    this.name = name; 
    } 
} 

class Employee extends Person { 
    constructor(name, company) { 
    super(name); 
    this.company = company; 
    } 
} 
+0

ええ、旧バージョンのブラウザを無視してこの実装を使用することはできますが、残念ながら古いバージョンのJSをサポートする必要があるため、これを使用することはできません。古いバージョンでこれと同等の処理を行う方法はありますか? –

+0

あなたはバーベルのレプリカを見て、彼らが何をしているか見ることができます。それは一番美しいものではありませんが、あなたが探しているものは間違いありません。 https://babeljs.io/repl/ –

+0

ありがとう、それは便利なツールです。それはカバーの下で間違いなく厄介ですので、私はおそらく、維持するのがちょっと簡単なので、私はおそらく今Ananthのアプローチに固執すると思います。 –

関連する問題