javascript: назначить функцию переменной заполняет переменную с неопределенным - PullRequest
0 голосов
/ 12 января 2020

Это своего рода c, но это вызывает у меня некоторые головные боли:

Я назначаю функцию переменной, затем вызываю функцию внутри первой функции из переменной.

Когда я назначаю функцию переменной, заполненной неопределенным значением, то при вызове внутренней функции я получаю ошибку:

Uncaught TypeError: Невозможно прочитать свойство 'add' из неопределенного

Это код, над которым я работаю:

(function () {

  function Sum() {

    this.result = 0;

    this.getCurrentSum = function getCurrentSum() {
      return this.result;
    }

    this.add = function add(add_number) {
      this.result += add_number;
    }

  }

  var s1 = Sum();  // here s1 is undefined
  var s2 = Sum();  // here s2 is undefined

  s1.add(10);  // here cannot execute add of undefined crash
  s1.add(20);

  s2.add(30);
  s2.add(5);

  // must print 30
  console.log(s1.getCurrentSum());

  // must print 35
  console.log(s2.getCurrentSum());

}());

Я могу изменить код в функции Sum, но не могу изменить остальную часть кода

Ответы [ 2 ]

4 голосов
/ 12 января 2020

Похоже, вы хотите, чтобы Sum была функцией конструктора . Вы вызываете функции конструктора через new, а не напрямую. Итак:

var s1 = new Sum();
var s2 = new Sum();

Причина, по которой вы получили undefined в s1 и s2 без new, заключается в том, что Sum нигде не выполняет return x, поэтому результат вызова это значение undefined. Но когда вы используете new, результатом выражения new будет объект, который был создан.

FWIW, возникает другая проблема с Sum: вы пропускаете this. в паре мест (также пара точек с запятой, хотя Automati c Вставка точки с запятой добавит их для вас):

function Sum() {
  this.result = 0;

  this.getCurrentSum = function getCurrentSum() {
    return this.result;
// −−−−−−−−^^^^^
  };

  this.add = function add(add_number) {
    this.result += add_number;
// −^^^^^
  };
}

JavaScript не похоже на Java или C#, this. не является обязательным.


В комментарии вы спросили:

Ват, могу ли я изменить функцию Сумма или что-то внутри функции, но я не могу изменить var s1 = Sum (); вызов?

В этом случае вы бы сделали функцию Sum builder и вернули бы объект, например так:

function Sum() {
  return {
    result: 0,
    getCurrentSum: function getCurrentSum() {
      return this.result;
    },
    add: function add(add_number) {
      this.result += add_number;
    }
  };
}

Live Пример:

(function () {

  function Sum() {
    return {
      result: 0,
      getCurrentSum: function getCurrentSum() {
        return this.result;
      },
      add: function add(add_number) {
        this.result += add_number;
      }
    };
  }

  var s1 = Sum();  // here s1 is undefined
  var s2 = Sum();  // here s2 is undefined

  s1.add(10);  // here cannot execute add of undefined crash
  s1.add(20);

  s2.add(30);
  s2.add(5);

  // must print 30
  console.log(s1.getCurrentSum());

  // must print 35
  console.log(s2.getCurrentSum());
})();

Обычно функция компоновщика не начинается с заглавной буквы (это по существу зарезервировано для функций конструктора), поэтому она будет иметь имя, например createSum или buildSum или аналогичные.

Эта версия Sum написана с синтаксисом уровня ES5 (на самом деле это даже уровень ES3). В ES2015 + это может быть более кратким:

// ES2015+ using method syntax
function Sum() {
  return {
    result: 0,
    getCurrentSum() {
      return this.result;
    },
    add(add_number) {
      this.result += add_number;
    }
  };
}

Live Пример:

(function () {

  // ES2015+ using method syntax
  function Sum() {
    return {
      result: 0,
      getCurrentSum() {
        return this.result;
      },
      add(add_number) {
        this.result += add_number;
      }
    };
  }

  var s1 = Sum();  // here s1 is undefined
  var s2 = Sum();  // here s2 is undefined

  s1.add(10);  // here cannot execute add of undefined crash
  s1.add(20);

  s2.add(30);
  s2.add(5);

  // must print 30
  console.log(s1.getCurrentSum());

  // must print 35
  console.log(s2.getCurrentSum());
})();
1 голос
/ 12 января 2020

Поскольку вы используете this в функции Sum, вам необходимо создать экземпляр этого объекта. Использование оператора new для использования Sum в качестве "функции конструктора" сделает sh этого.

Но затем в Sum вы объявите this.result как переменная экземпляра, поэтому вы также должны ссылаться на нее как this.result в других местах функции.

Взгляните на другой мой пост , в котором говорится о this и что он делает.

(function () {
  function Sum() {
    this.result = 0;
    this.getCurrentSum = function getCurrentSum() {
      return this.result;
    }
    this.add = function add(add_number) {
      this.result += add_number;
    }
  }

  var s1 = new Sum();
  var s2 = new Sum();

  s1.add(10);
  s1.add(20);

  s2.add(30);
  s2.add(5);

  console.log(s1.getCurrentSum());  // 30
  console.log(s2.getCurrentSum());  // 35
}());
...