Christian
Christian

Reputation: 859

Javascript new keyword in subfunctions

I´m trying to sort out how 'new' keyword is working in Javascript. But it is has a strange behaviour.
When I run this code in node:

var testing = function() {
  self = this;
  this.abc = 'abc';
  console.log(this); // ====> 1

  var subMethod = function () {
    console.log(this);  // =====> 2
    console.log(self === this); // ====> 3
  };
  //subMethod.apply(this);
  subMethod();
};


test = new testing();
// test = testing(); // ===> *4

The console.log(self === this) gives me false. 'this' in nr 1 is { abc: 'abc' }, and 'this' in the sub method is the global 'this' object. Can anyone give me an explanation for this behaviour?
If I run with subMethod.apply(this) then console.log(self === this) is true ({ abc: 'abc' })

When I run without the new keyword (*4) the 'this' variable is the same as the global 'this' (as expected), and also the console.log(self === this) is true.

Why is 'this' in the submethod the same as the global 'this' when running with the 'new' keyword.

Upvotes: 3

Views: 60

Answers (1)

Scimonster
Scimonster

Reputation: 33409

When you call new testing(), the function testing is run with its context (this) as a new object. The first log will be that object. Inside, when you run subMethod(), it's run in the global context. That's just how JS does it. Therefore, this is window, and self !== this. If you call it with your this context (subMethod.apply(this)), so naturally self === this.

When you call testing(), it's run in global context. When you add abc, that's now global, as this is window. When you call subMethod(), it's also called in global context by default, and as such self === this.

So basically, running a plain function is in global context. Running a function as a constructor (with new) creates a new context. Running a method (e.g. "abaca".split('a')) is called in the context of the base object - split is called with "abaca" as its this.

Does that help?

Upvotes: 1

Related Questions