1

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
2
  • 1
    Because this is not what you think it is. Try alert(this); just before this.value++ and you'll see. Commented Feb 24, 2015 at 17:42
  • This page explains what you are experiencing, and also has an example similar to your code. snook.ca/archives/javascript/javascript_pass Commented Feb 24, 2015 at 17:46

3 Answers 3

2
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);
Sign up to request clarification or add additional context in comments.

Comments

2

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

Comments

1

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

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.