en.javascript.info/1-js/8-oop/3-getters-setters/4-setter-onready/solution.md
Ilya Kantor 87bf53d076 update
2014-11-16 01:40:20 +03:00

1.8 KiB
Raw Blame History

//+ run
function CoffeeMachine(power, capacity) {
  var waterAmount = 0;

  var WATER_HEAT_CAPACITY = 4200;
  function getTimeToBoil() {
    return waterAmount * WATER_HEAT_CAPACITY * 80 / power;
  }

  this.setWaterAmount = function(amount) {
    // ... проверки пропущены для краткости
    waterAmount = amount;
  };

  this.getWaterAmount = function(amount) {
    return waterAmount;
  };

  function onReady() {
    alert('Кофе готов!');
  }

*!*
  this.setOnReady = function(newOnReady) {
    onReady = newOnReady;
  };
*/!*

  this.run = function() {
*!*
    setTimeout(function() { onReady(); }, getTimeToBoil());
*/!*
  };

}

var coffeeMachine = new CoffeeMachine(20000, 500);
coffeeMachine.setWaterAmount(150);

coffeeMachine.run();

*!*
coffeeMachine.setOnReady(function() {
  var amount =  coffeeMachine.getWaterAmount();
  alert('Готов кофе: ' + amount + 'мл'); // Готов кофе: 150 мл
});
*/!*

Обратите внимание на два момента в решении:

  1. В сеттере `setOnReady` параметр называется `newOnReady`. Мы не можем назвать его `onReady`, так как тогда изнутри сеттера мы никак не доберёмся до внешнего (старого значения):
    // нерабочий вариант
    this.setOnReady = function(onReady) {
      onReady = onReady; // ??? внешняя переменная onReady недоступна
    };
    
  2. Чтобы `setOnReady` можно было вызывать в любое время, в `setTimeout` передаётся не `onReady`, а анонимная функция `function() { onReady() }`, которая возьмёт текущий (установленный последним) `onReady` из замыкания.