Подтвердить что ты не робот

Почему моя переменная undefined внутри Underscore.js для каждой функции?

Вот мой код:

TextClass = function () {
    this._textArr = {};
};

TextClass.prototype = {
    SetTexts: function (texts) {
        for (var i = 0; i < texts.length; i++) {
            this._textArr[texts[i].Key] = texts[i].Value;
        }
    },
    GetText: function (key) {
        var value = this._textArr[key];
        return String.IsNullOrEmpty(value) ? 'N/A' : value;
    }
};

Я использую библиотеку Underscore.js и хотел бы определить мою функцию SetTexts следующим образом:

_.each(texts, function (text) {
    this._textArr[text.Key] = text.Value;
});

но _textArr undefined, когда я попадаю в цикл.

4b9b3361

Ответ 1

В JavaScript контекст функции, известный как this, работает по-другому.

Вы можете решить это двумя способами:

  • Используйте временную переменную для хранения контекста:

    SetTexts: function (texts) {
      var that = this;
      _.each(texts, function (text) {
        that._textArr[text.Key] = text.Value;
      });
    }
    
  • Используйте третий параметр _.each(), чтобы передать контекст:

    SetTexts: function (texts) {
      _.each(texts, function (text) {
        this._textArr[text.Key] = text.Value;
      }, this);
    }
    

Ответ 2

Вы должны передать this в качестве контекста для вызова _.each следующим образом:

_.each(texts, function (text) {
    this._textArr[text.Key] = text.Value;
}, this);

Смотрите документы для http://underscorejs.org/#each

Ответ 3

this в javascript работает не так, как вы ожидали. прочитайте эту статью: http://www.digital-web.com/articles/scope_in_javascript/

короткая версия:

значение this изменяется при каждом вызове функции. для исправления, установите другую переменную, равную this, и укажите, что вместо этого

TextClass = function () {
    this._textArr = {};
};

TextClass.prototype = {
    SetTexts: function (texts) {
        var that = this;
        for (var i = 0; i < texts.length; i++) {
            that._textArr[texts[i].Key] = texts[i].Value;
        }
    },
    GetText: function (key) {
        var value = this._textArr[key];
        return String.IsNullOrEmpty(value) ? 'N/A' : value;
    }
};

Ответ 4

Обратите внимание, что вы также можете передавать другие вещи, которые "this". Например, я делаю что-то вроде:

var layerGroupMasterData = [[0],[1,2,3],[4,5],[6,7,8,9],[10]];

_.each(layerGroupMasterData,function(layerGroup,groupNum){
    _.each(layerGroup, function (layer, i) {
            doSomethingThatComparesOneThingWithTheOverallGroup(layerGroupMasterData,layer);
    },layerGroups);
},layerGroupMasterData);