1

I've run into a - what seems - somewhat strange problem. Let's say I have a JavaScript object like this one:

var Object = {
    Property1: 0,
    Property2: 1,
    TxtProperty: "Sample text",

    Update: function () {
        this.Property1++;                      // Doesn't work
        Object.Property2++;                    // Does work
        this.TxtProperty = "Hello world";      // Does work

        $('#prop-1').text(this.Property1);     // Prints NaN
        $('#prop-2').text(Object.Property2);   // Prints correct value
        $('#txt-prop').text(this.TxtProperty); // Prints correct value
    }
};

See this fiddle for a demonstration. Click 'Start' to start the timer and update the values. As you can see, using parseInt didn't help either.

I've tested this in Firefox, Chrome, and IE10. They all show the same behavior.

Why can't you reference a property with a numeric value using this from inside another property with a function value? Why does it work with non-numeric values? Is this a bug or is this intended?

This is not so much a real problem as we can simply use the parent object's name to update the numeric value, but I'm just curious as to why this is so.

4
  • I think this will refer to Window the way you use it. Not to parent object. Commented May 16, 2013 at 7:49
  • But then surely this.TxtProperty shouldn't work either. Commented May 16, 2013 at 7:51
  • 1
    It work because it creates a new window.TxtProperty property. Commented May 16, 2013 at 7:52
  • 1
    Try looking at Object.TxtProperty after that, you'll see that it didn't change. Commented May 16, 2013 at 7:53

1 Answer 1

2

setTimeout runs the function in the window context so this inside of it refers to window. If you bind the proper this context, then it'll work fine:

interval = setInterval(Object.Update.bind(Object), 1000);
                                     -----^------

Demo: http://jsfiddle.net/wC2uM/2/

bind only works in modern browsers so if you need support for old IE use an anonymous function:

interval = setInterval(function(){ Object.Update(); }, 1000);

Remember that in JavaScript this depends on how you call the function; it's mutable.

Sign up to request clarification or add additional context in comments.

1 Comment

You can simplify Object.Update.call(Object); to Object.Update(); ;)

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.