1

Hello I am stuck on a case I don't get

here is the code

function car(speed) {
    this.speed = speed; 
    this.accelerate = function() {
        this.speed += 1;
    }
}

var oldcar = new car(1);

function test(cb){
  cb();
}

test(oldcar.accelerate);

console.log(oldcar.speed);
// 1

test(function(){ oldcar.accelerate(); });

console.log(oldcar.speed);
// 2

On the first function call test(), I observe that the this in the oldcar.accelerate method is set to window.

On the second case, the this is correctly set to oldcar.

I don't understand how calling test() with oldcar.accelerate instead of function(){ oldcar.accelerate(); } make such a difference.

Can someone explain the behavior ? thanks !

decarte
  • 359
  • 1
  • 4
  • 14
  • 1
    Because that's how `this` is meant to be: it's meaning depends on how you call the function. – Álvaro González Jan 10 '17 at 15:34
  • 2
    [Comprehensive related Q&A](http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – James Thorpe Jan 10 '17 at 15:38
  • 1
    because `thisParticularObjectReference.fn(arg)` is equivalent to `thisParticularObjectReference.fn.call(thisParticularObjectReference, arg)`, whereas using a reference to the function to call it `var fn = obj.fn; fn(arg)` is equivalent to `fn.call(undefined, arg)` wich sets `this` to the global object *(without 'use strict')* – Thomas Jan 10 '17 at 15:46

1 Answers1

1

Because when you pass a method as a callback you are passing only the method, not the object which it belongs to.

When this is used in without any given scope, it defaults to window (or the closest surrounding scope).

A correct way is to pass the entire object, or an anonymous function has has access to the entire object..

function test(cb){
  cb();
}

test(function(){ oldcar.accelerate() });
I wrestled a bear once.
  • 19,489
  • 16
  • 63
  • 110
  • 1
    An equally correct way would be to pass it an anonymous function, then in that call your object method. That way `test` doesn't care what it receives, so long as its a method. – ste2425 Jan 10 '17 at 15:59
  • AHH ok your answer make complete sence with the comment of thomas. "thisParticularObjectReference.fn(arg) is equivalent to thisParticularObjectReference.fn.call(thisParticularObjectRe‌​ference, arg)" – decarte Jan 10 '17 at 16:02
  • 1
    think about it like this.. if i wanted to slap you i wouldn't cut my arm off and mail it to you, my arm wouldn't know what to do when it arrives. the only way i can slap you is to send my whole self to you :) – I wrestled a bear once. Jan 10 '17 at 16:04