1

Having the following code, the output is undefined when calling the Play method from my object instance while I was expecting the 'this' keyword to reference the global variable and display "Football" in lack of a PlayGound's scope variable.

var game = "Football";

function Play() {
  console.log(this.game)
}

function PlayGround() {
  this.Play = Play;
}

var obj = new PlayGround();
obj.Play();

Now, invoking the Play() at constructor level, without passing it's reference to a local variable the output is "Football".

var game = "Football";

function Play() {
  console.log(this.game)
}

function PlayGround() {
  Play();
}

var obj = new PlayGround();

Can someone explain the reason why those two aproaches behave differently?

Patrick Roberts
  • 40,065
  • 5
  • 74
  • 116
  • 1
    It doesn't matter *where* it is called, it matters *how* it is called - `obj.Play()` vs. `Play()`. You also should use strict mode. – Bergi Nov 24 '18 at 17:53

1 Answers1

3

The first one outputs undefined very simply because obj does not have a game property. That can be fixed like this:

var game = "Football";

function Play() {
  console.log(this.game)
}

function PlayGround() {
  this.game = game;
  this.Play = Play;
}

var obj = new PlayGround();
obj.Play();

The second snippet is bad practice because it relies on mechanics of non-strict mode simple calls in order to work.

If you change the second snippet to strict mode it will error because this in simple calls is undefined instead of window:

"use strict";

var game = "Football";

function Play() {
  console.log(this.game)
}

function PlayGround() {
  Play();
}

var obj = new PlayGround();

If you use let or const declaration for game, the second snippet will output undefined because those top-level declarations do not attach to the global scope window:

let game = "Football";

function Play() {
  console.log(this.game)
}

function PlayGround() {
  Play();
}

var obj = new PlayGround();
Patrick Roberts
  • 40,065
  • 5
  • 74
  • 116