2016-02-17 5 views
5

RubyのバックグラウンドからJavaScriptを学習しているので、私のコードが結果を生成できない理由を理解しています必要。私はpythontutor.comでこれを実行して何が起きているのかを段階的に見てみると、それは私の疑惑を裏付けるものです。しかし、なぜこれが当てはまるのか正確にはわかりません。JavaScriptの関数とプロトタイプ - 呼び出しメソッドによる基本的なルーティングの問題

私はサーモスタットを構築していて、温度が18dCを下回ったら 'グリーン'に戻ると思われます。最後の行でthermostat.displayColorと呼ぶと、私の最後から二番目の行でconsole.logは17ですが、黄色と表示されます。コードはそこで終了し、私はそれが期待しているthis.displayColor = this.currentColor()に戻ることはありません(最初の実行時に '黄色'として開始色を定義して以来)

コードが正しく動作し、私は直接プロトタイプメソッドthis.currentColor()を呼び出すコードを変更した場合、しかし、私はちょうど私が、私は以下の書いた方法でそれをやるせていない理由を知りたい。

私はこれを説明する用語のわからないんだけど問題は、私のタイトルは正確ではないため、事前に謝罪そう。

var DEFAULT_TEMP = 20; 

function Thermostat(){ 
    this.temperature = DEFAULT_TEMP; 
    this.maxTemp = 25; 
    this.powerMode = 'on'; 
    this.displayColor = this.currentColor() 
}; 

Thermostat.prototype.downButton = function(){ 
    if (this.temperature === 10){ 
    throw new Error('temp cannot be lower than 10dC'); 
    }; 
    this.temperature --; 
}; 

Thermostat.prototype.currentColor = function() { 
    if ((this.temperature >= 18) && (this.temperature < 25)) { 
    return 'yellow' 
    } 
    else if (this.temperature < 18) { 
    return 'green' 
    } 

    else { 
    return 'red' 
    } 
}; 

var thermostat = new Thermostat(); 
for (var i = 1; i <= 3; i++) { 
     thermostat.downButton(); 
     }; 
console.log("spec file test green, temp should be 17 and is:" + thermostat.temperature) 
console.log(thermostat.displayColor); //this should be green, but it is yellow! 

答えて

3

あなたが呼び出す必要がありますcurrentColor()メソッドdisplayColorは、コンストラクター(温度が20の場合)にのみ設定され、温度が変化すると更新されません。

それはdownButton方法に色の設定を追加しても意味があります:ロブが言うように、あなたが現在の色を計算する関数を呼び出す必要があり、

Thermostat.prototype.downButton = function(){ 
    if (this.temperature === 10){ 
    throw new Error('temp cannot be lower than 10dC'); 
    }; 
    this.temperature --; 
    this.displayColor = this.currentColor(); 
}; 
+0

は、迅速な対応のためにあなたにロブをありがとう! displayColorが(初期化の時点で)1回だけ設定される理由は何か特別な理由はありますか?私はこれについてもっと詳しく知りたいと思いますが、おそらく本当に基本的なコンセプトですが、コンストラクタ関数を呼び出すインスタンスを作成するたびに、これを探し始める方法がわかりません。 – ugotchi

+1

@ggwcそれは 'Thermostat()'関数が呼び出される唯一の時間です。したがって、 'displayColor()'は一度だけ呼び出されます。 – Sean

+1

@ggwc問題ありません。おそらく、 'this.displayColor = this.currentColor()'は 'displayColor'の値をバインドし、その値を得るために常に' currentColor'関数を呼び出すことが何らかの形で行われると考えています。コンストラクタ( 'Thermostat(){...')は、 'new Thermostat()'をインスタンス化したときに一度呼び出され、他のメンバ関数や外部から更新されない限り、コンストラクタ内で設定した値は静的です。 –

2

。ここでは彼の提案はあなたのコードにいくつかの改善と一緒です:

function Thermostat() { 
 
    this.MIN_TEMP = 10; 
 
    this.MAX_TEMP = 25; 
 
    this.temperature = 20; 
 
} 
 

 
Thermostat.prototype.decreaseTemp = function() { 
 
    if (this.temperature > this.MIN_TEMP) this.temperature--; 
 
}; 
 
Thermostat.prototype.increaseTemp = function() { 
 
    if (this.temperature < this.MAX_TEMP) this.temperature++; 
 
}; 
 
Thermostat.prototype.currentColor = function() { 
 
    if (this.temperature < 18) return 'green'; 
 
    if (this.temperature < 25) return 'yellow'; 
 
    return 'red'; 
 
}; 
 

 
var thermostat = new Thermostat(); 
 
for (var i = 1; i <= 3; i++) { 
 
    thermostat.decreaseTemp(); 
 
} 
 

 
// no errors mean all assertions pass 
 
thermostat.temperature.should.equal(17); 
 
thermostat.currentColor().should.equal('green');
<script src="https://cdnjs.cloudflare.com/ajax/libs/should.js/8.2.2/should.min.js"></script>

関連する問題