2016-11-09 17 views
0

私の現在のWebプロジェクトでは、それぞれが他の型から継承した型定義を含む複数のJavaScriptファイルを扱っています。に面倒になり、多くのJavaScriptファイルを扱うのでJavaScript継承とホイスト

function ParentType(){ 
    this.data = "";  
}  

:だから、任意のファイルで、私は別のファイルにも同様に宣言ParentTypeで... ...のような

function Type(){ 
    ParentType.call(this); 
} 
Type.prototype = Object.create(ParentType.prototype); 
Type.prototype.constructor = Type; 

を何かを持っている可能性があり<head>タグでは、ファイルを1つのファイル(master.js)に連結するbashスクリプトを書いています。そうすれば、私は自分のHTMLで1つのファイルをリンクすることができます。

子が1つだけのタイプの場合、ファイルの連結順序に関係なく、プロトタイプチェーンが正しく構築されます。

function Type(){ 
    ParentType.call(this); 
} 
Type.prototype = Object.create(ParentType.prototype); 
Type.prototype.constructor = Type; 

function ParentType(){ 
    this.data = ""; 
} 

私はいずれのシナリオでTypeのインスタンスを作成すると、ParentType.prototype.isPrototypeOf(typeobj)戻る真(typeobjである。換言すれば、このスニペットは...

function ParentType(){ 
    this.data = ""; 
} 

function Type(){ 
    ParentType.call(this); 
} 
Type.prototype = Object.create(ParentType.prototype); 
Type.prototype.constructor = Type; 

...このスニペットと同じ作用します私のインスタンスはTypeです)。しかし

、私は「プロトタイプチェーン」、ファイルが順に連結されているときにのみ機能、すなわちの最後に別のタイプを追加します。

function ParentType(){ 
    this.data = ""; 
} 

function Type(){ 
    ParentType.call(this); 
} 
Type.prototype = Object.create(ParentType.prototype); 
Type.prototype.constructor = Type; 

function ChildType(){ 
    Type.call(this); 
} 
ChildType.prototype = Object.create(Type.prototype); 
ChildType.prototype.constructor = ChildType; 

...とそうでない場合は、チェーン」休憩 "。私が一人の子供のシナリオで大丈夫だと思うのは、両方の型定義が吊り上げられ、プロトタイプチェーンについて心配するステートメントのセットが1つしかないからです。しかし、マルチリンクのプロトタイプチェーンでは、ステートメントが順不同であれば、チェーンは正しく接続されません。

私が本当に求めているのは、は、ファイルが連結されている順番に関係なく、JavaScriptで継承を実装する方法です。私は最初にclassextendsのやり方をしていましたが、それでもclassの定義が吊り上げられていないことを知っていました!

注:「作品」で、私が意味するすべてのサブタイプは、両親、そしてその両親のプロトタイプのいずれに対してチェック任意のオブジェクトのための真isPrototypeOfリターン(すべての)から機能/値を継承という点です。

答えて

0

は、チェーンが適切に接続するために失敗しました。

はい。 ChildType.prototypeを作成する前に、Type.prototypeを設定する必要があります。これは、関数宣言の巻き上げに何もする必要はありません。

JavaScriptで継承を実装する方法は、ファイルが連結されている順序に関係なく「機能する」ことがありますか?

さて、あなたはObject.setPrototypeOfを使用することがありますすることができます

function ChildType(){ 
    Type.call(this); 
} 
Object.setPrototypeOf(ChildType.prototype, Type.prototype); 

function Type(){ 
    ParentType.call(this); 
} 
Object.setPrototypeOf(Type.prototype, ParentType.prototype); 

function ParentType(){ 
    this.data = ""; 
} 

しかし、あなたはは本当にその方法を避けたい、とこのように巻き上げに頼ることは非常に悪い習慣ですので、あなた実際に正しい順序を使用するように連結スクリプトを修正する必要があります。あるいは、あなたのために依存関係を明らかにするモジュールシステムを使用してください。

私の最初は、しかしclassや物事のextends方法でしたが、その後私もclass定義が掲揚されていないことを学びました!

That's a good thing。それらを純粋に砂糖であるとみなしてください。階層に沿って、常に正しい順序でそれらを設定する必要があります。

+0

+1は実際の質問に答えるために、これは私が探していたもの(私の他の選択肢を探究する)です。外部ソースを使いたい場合を除いて、スクリプトを洗練させないようにする良い方法はないようです。 – user1819699

0

機能は吊り下げられているため、順序が間違っている可能性がありますが、プロトタイプを連鎖させる呼び出しは順番に行う必要があります。

これらが順不同の場合、ホスティング後にコードは次のようになります。ある

function ParentType(){ 
    this.data = ""; 
} 

function Type(){ 
    ParentType.call(this); 
} 

function ChildType(){ 
    Type.call(this); 
} 
ChildType.prototype = Object.create(Type.prototype); 
ChildType.prototype.constructor = ChildType; 

Type.prototype = Object.create(ParentType.prototype); 
Type.prototype.constructor = Type; 

は、あなたがType.prototypeからChildType.prototypeをチェーンして、あなたはParentType.prototypeにチェーンそれにType.prototypeを上書きします。

この作業を順不同にする方法はありません。JavaScriptの継承は、順番に呼び出されるコード行に依存します。

+0

私はこれをすでに知っています。コードの順序が重要でないところで継承を実装する方法があるかどうかを尋ねています。 – user1819699

+1

既に知っていれば、なぜあなたの質問はホスティングに言及していますか? –

0

これを行う1つの方法は、各タイプに静的な初期化子を宣言することです。

ただし、これは実行時にのみ可能です(Object.crate経由または割り当てによる)ので、開始時に戻っています。あなたのファイルが実際にランダムな順序で連結されている場合は、タイプが作成され、親が作成されるまでサブタイプを「保留」にするような一種の「ファクトリ」関数を使用するより複雑なメカニズムを使用する必要があります。単に説明のため

簡体例:文の順序がある場合は、マルチリンクのプロトタイプチェーンの

function factory(precondition, callback) 
{ 
    if(!this.registry) this.registy = []; 
    if(!precondition || this.registry[precondition]) 
     this.registry[callback()] = true; 
    else setTimeout(function(){factory(precondition, callback);}, 100); 
} 

factory('Type', function() 
{ 
    Window.ChildType = function(){} 
    return 'ChildType'; 
}); 

factory(null, function() 
{ 
    Window.Type= function(){} 
    return 'Type'; 
});