0

prototypal-inheritanceを使用する一般的な抽象化を使用するjavascriptのファクトリパターンの例を作成しようとしましたが、コンソールログの値は未定義に戻ります。以下継承されたJavascriptオブジェクトがプロパティ値を失う

var AthleteFactory = function() { 
    var athlete, that = this; 

    this.createAthlete = function(athleteType, athleteName, athleteCountry, athleteUnit) { 
     switch (athleteType) { 
      case "Swimmer": 
       athlete = new Swimmer(athleteName, athleteCountry, athleteUnit); 
       break; 
      case "Runner": 
       athlete = new Runner(athleteName, athleteCountry, athleteUnit); 
       break; 
     } 

     return athlete; 
    } 
}; 

コンストラクタである:

function Athlete(theName, theCountry, theUnit) { 
    this.name = theName; 
    this.country = theCountry; 
    this.distance = 0; 
    this.unit = theUnit; 
}; 

選手オブジェクト(抽象/ベースオブジェクト)

Athlete.prototype = { 
    constructor: Athlete, 
    recordDistance: function(distance) { 
     this.distance += distance; 
    }, 
    showProgress: function() { 
     $("#output").append("<h1>" + this.name + " of " + this.country + " has achieved: " + this.distance + this.unit + "</h1>"); 
    }, 
}; 

DoExercise論理違いが含ま

var Swimmer = function(theName, theCountry, theUnit) {}; 
Swimmer.prototype = new Athlete(); 
Swimmer.prototype.DoExercise = function(difficulty) { 
    switch (difficulty) { 
     case "easy": 
      this.recordDistance(20); 
      break; 
     case "moderate": 
      this.recordDistance(50); 
      break; 
     case "hard": 
      this.recordDistance(100); 
      break; 
    }; 
}; 

アスリートベースオブジェクトを拡張従って工場出荷時のパターン

var Runner = function(theName, theCountry, theUnit) {}; 
Runner.prototype = new Athlete(); 
Runner.prototype.DoExercise = function(difficulty) { 
    switch (difficulty) { 
     case "easy": 
      this.recordDistance(5); 
      break; 
     case "moderate": 
      this.recordDistance(20); 
      break; 
     case "hard": 
      this.recordDistance(60); 
      break; 
    }; 
}; 
//create some athletes in our factory 
var factory = new AthleteFactory(); 

var phelps = factory.createAthlete("Swimmer", "Micheal Phelps", "USA", "Metres"); 
console.log(phelps); 

var farah = factory.createAthlete("Runner", "Mo Farah", "UK", "Kilometres"); 
console.log(farah); 

phelps.DoExercise("easy"); 
phelps.DoExercise("moderate"); 
phelps.DoExercise("hard"); 
phelps.showProgress(); //undefined of undefined has achieved: 170undefined 

farah.DoExercise("moderate"); 
farah.DoExercise("easy"); 
farah.DoExercise("hard"); 
farah.showProgress(); //undefined of undefined has achieved: 85undefined 

私はC#の背景ではなく、JavaScriptから私は潜在的に根本的な違いや2を誤解してるんです。私はちょうどこの作業を取得するためにいいだろうと同じタスクを達成するために、別の関数を作成することもできますが、ここで

がcodepenリンクです:あなたのスイマーとランナーのコンストラクタで http://codepen.io/paulcthomas/pen/aNLJyq?editors=1010

+1

JSの仕組みを理解するためにC#の知識に頼っていますか? –

+1

この例は、Javascriptオブジェクトとサブクラスで始めるだけの人にとっては単純すぎる方法です。既存のチュートリアルの作業例をいくつか紹介し、それらを拡張してテストして、どのように動作するかを確認してください。とりわけ、 'Object.create()'を使ってプロトタイプを初期化し、 'that = this'のようなものをファクトリ関数内で使うのは意味がありません。真剣に、Javascriptのチュートリアルに続き、あなたがC++から知っていたと思ったほとんどのものを忘れてしまったら、あなたの方法で手に入ります。 – jfriend00

+0

おそらくこれはちょっとしたポイントですが、C#とjavascriptが少し微妙**(笑い止め)なので、もっと簡単な例から始めてください。 「工場」パターンを作成する方法はたくさんありますが、いくつかのjavascriptチュートリアル(主に匿名関数、**自己呼び出し匿名関数**、非同期コールバック、将軍のコールバック)を確認する必要があります。もう一度、あなたはまだそれを達成することはできませんが、あなたの例は、初心者に対処する必要がある多くの点があるので、JavaScriptの初心者のために非常に複雑です。 – briosheje

答えて

0

、あなたが呼び出す必要があります基本クラスのコンストラクタは次のようになります。

0

あなたが実際に望むのは、サブクラスでコンストラクタを継承することです。これはJSでは自動的には発生しません。サブクラスのconstrcutorで親クラスのコンストラクタを手動で呼び出す必要があります。

同じパターンを使用しているthis articleのように、一般的な解決策はこれです。

この時点で
var Swimmer = function(theName, theCountry, theUnit) { 
    Athlete.apply(this, arguments) 
}; 

ない場合は読みやすいあなたもinheretingたときにスーパークラスのコンストラクタが自動的に呼び出され

var Runner = function() { 
    Athlete.apply(this, arguments) 
}; 

あなたのサブクラスのコンストラクタに引数を定義することができませんでした。 最初に継承することは醜くない方法はありませんし、何かを実行してから、 スーパークラスのコンストラクタを呼び出します。

+0

例が更新され、余分な= thisを削除しました。私は親のコンストラクタ継承と "適用"メソッドについては理解していませんでした。 – MagicLuckyCat

関連する問題