3

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.

Scimonster
  • 30,695
  • 8
  • 67
  • 84
Christian
  • 685
  • 7
  • 23
  • When applying this.subMethod = function.... . Then the this scope is as I expect { abc: 'abc', subMethod: [Function] } – Christian Nov 11 '14 at 09:09
  • Related: http://stackoverflow.com/questions/111102 It doesn't *explicitly* discuss `new` but there's really nothing special about it -- it works exactly as you'd expect; the closures are the tricky bit – blgt Nov 11 '14 at 09:16

1 Answers1

1

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?

Scimonster
  • 30,695
  • 8
  • 67
  • 84