19

Here is my code:

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;
    }
};

I'm using the Underscore.js library and would like to define my SetTexts function like this:

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

but _textArr is undefined when I get into the loop.

1
  • 8
    Because this inside the callback is not the same as outside it. Use the third parameter to each to pass the context you want to have inside the callback. Commented Nov 13, 2012 at 6:01

4 Answers 4

38

In JavaScript, the function context, known as this, works rather differently.

You can solve this in two ways:

  1. Use a temporary variable to store the context:

    SetTexts: function (texts) {
      var that = this;
      _.each(texts, function (text) {
        that._textArr[text.Key] = text.Value;
      });
    }
    
  2. Use the third parameter to _.each() to pass the context:

    SetTexts: function (texts) {
      _.each(texts, function (text) {
        this._textArr[text.Key] = text.Value;
      }, this);
    }
    
Sign up to request clarification or add additional context in comments.

Comments

6

You have to pass this as context for _.each call like this:

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

See the docs for http://underscorejs.org/#each

1 Comment

Works like charm! Thanks a million to all repliers :-)
1

this in javascript does not work the same way as you would expect. read this article: http://www.digital-web.com/articles/scope_in_javascript/

short version:

the value of this changes every time you call a function. to fix, set another variable equal to this and reference that instead

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;
    }
};

Comments

0

Note that you can also pass things other that "this". For example, I do something like:

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.