Несколько экземпляров объектов, использующих ту же функцию, что и самый новый экземпляр - PullRequest
0 голосов
/ 26 февраля 2020

Я столкнулся с этой проблемой при создании функции для библиотеки Javascript. Насколько я могу судить, когда функция объекта использует комбинацию замыкания и обещания, последняя созданная версия будет использоваться для всех экземпляров. Вывод приведенного ниже кода «3» повторяется три раза. Тем не менее, когда я добавляю var перед строкой, определяющей logSecret, результат будет равен 1 2 3, что я и ожидал.

Почему несколько экземпляров объекта в конечном итоге используют то же значение?

Почему добавление var перед закрытием решает проблему?

К сожалению, я не знаю Javascript достаточно хорошо, чтобы понять, что именно здесь происходит, так что я надеюсь, что кто-то сможет пролить свет на то, что здесь происходит. Спасибо!

function MyObject(myValue){
  var _this = this;
  _this.secret = myValue;
  _this.foo = function() {
    makePromise = function() {
      var promise = $.Deferred();
      promise.resolve("done");
      return promise;
    }
    logSecret = function() {
      console.log(_this.secret);
    }

    var promise = makePromise();
    $.when(promise).then(function (data) { logSecret(); });
  }
}

var obj1 = new MyObject(1);
var obj2 = new MyObject(2);
var obj3 = new MyObject(3);
obj1.foo();
obj2.foo();
obj3.foo();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

1 Ответ

2 голосов
/ 26 февраля 2020

В нестрогом режиме, когда переменные не объявлены явно с var, let или const, создается неявная глобальная переменная. ie. такие переменные ведут себя так, как если бы они были объявлены в глобальном контексте.

В вашем коде переменные makePromise и logSecret явно не объявлены и поэтому используются всеми вызовами MyObject.

Итак, каждый раз, когда вызывается MyObject, makePromise и logSecret перезаписываются новым экземпляром объекта функции, который закрывается в лексической среде для последнего вызова MyObject.

Последний вызов MyObject закрывается по секретному значению 3, отсюда и наблюдаемое поведение.

function MyObject(myValue) {
    var _this = this;
    _this.secret = myValue;
    _this.foo = function() {
        makePromise = function() { // global variable
            var promise = $.Deferred();
            promise.resolve("done");
            return promise;
        }

        logSecret = function() { // global variable
            console.log(_this.secret);
        }

        var promise = makePromise();
        $.when(promise).then(function(data) {
            logSecret();
        });
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...