ʞɹᴉʞ ǝʌɐp
ʞɹᴉʞ ǝʌɐp

Reputation: 5650

Javascript Gotcha: Why value does not increment?

Why is the value for "o.value" unchanged when changer(o.inc) is called?

Fiddle: http://jsfiddle.net/illumine/qbr9xupt/

function customobject(){
    this.value = 2;
}

customobject.prototype.inc = function(){
    this.value++;
}

function changer(func){
    func(); 
}

var o = new customobject();
alert(o.value); // o.value = 2

o.inc();
alert(o.value); // o.value = 3

changer(o.inc);
alert(o.value); // Still 3 why not 4

Upvotes: 1

Views: 153

Answers (3)

nderscore
nderscore

Reputation: 4251

changer(o.inc);

You're passing a reference to the inc function here. This reference has no association with the o object. When you call the function, this is this context is the global scope (window).

You could bind o as this to your function before passing it to changer like this:

changer(o.inc.bind(o));

But the Function.prototype.bind method isn't supported IE8 and below. A simple alternative solution would be to wrap the function like this:

changer(function(){ return o.inc(); });

Or alternatively, you could use Function.prototype.call to call the function with o as this and pass a reference to the object.

function changer(_this, func){
    func.call(_this);
}
...
changer(o, o.inc);

Upvotes: 2

javinor
javinor

Reputation: 674

Understanding how this behaves is not trivial and very important. I'd recommend taking a look at http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/

when calling a method like a regular function, this is bound to the global object, so o.inc doesn't change. You can try this as well:

var foo = o.inc;
foo();
console.log(o.value); // still 3

Upvotes: 1

Jacob
Jacob

Reputation: 78850

o.inc gives you a reference to a function that, when called, does not carry with it the this it came from (one of the huge challenges in JS). To work around it, do this:

changer(o.inc.bind(o));

The bind method on a function can cement it to a this (as well as do currying if you'd like).

Upvotes: 2

Related Questions