7

I was under the impression that the "this" keyword represents the current owner that is in scope. Obviously, this is wrong. Let me get to the code:

alert(this);     // alerts as [object Window] -- Okay

function p1() {
    alert(this);
}

var p2 = function() {
    alert(this);
}

p1();           // alerts as undefined  -- ???
p2();           // alerts as undefined  -- ??
window.p1();    // alerts as [object Window] -- Okay
window.p2();    // alerts as [object Window] -- Okay

The code above first alerts [object Window], as I would expect but then the next two calls to p1() and p2() alert "this" as "undefined". The final two calls to p1() and p2() alert "this" as [object Window].

Isn't it the case that p1() and p2() exist in the global (i.e., window) scope? I thought that calling window.p1() is synonymous with calling p1(), just like calling alert() is synonymous with window.alert().

To my (C#) way of thinking, p1() and p2() are in the global scope. These functions are members of the global window object so when they refer to "this" they should be referring to [object Window]. Obviously, I'm very wrong here.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Tom Baxter
  • 2,110
  • 2
  • 19
  • 38
  • 13
    looks like you are running the script in strict mode – Arun P Johny Jul 10 '15 at 12:19
  • runs fine on Chrome console.. I get `[object Window]` for all the alerts! – Sudhansu Choudhary Jul 10 '15 at 12:20
  • the issue is strict mode. running the code you've put here does as you'd expect and alerts window for all alerts – atmd Jul 10 '15 at 12:20
  • see the second para in https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Strict_mode#Securing_JavaScript – Arun P Johny Jul 10 '15 at 12:22
  • @ArunPJohny I'm using `use strict` and it works fine, albeit on Chrome console. Does the console neglect it?? – Sudhansu Choudhary Jul 10 '15 at 12:22
  • when I try this in firefox with strict mode in the console I get `undefined`. However chomre does appear to be alerting `window` – atmd Jul 10 '15 at 12:22
  • 1
    http://jsfiddle.net/arunpjohny/287rvmkc/1/ & http://jsfiddle.net/arunpjohny/287rvmkc/2/ – Arun P Johny Jul 10 '15 at 12:24
  • also read - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this – Arun P Johny Jul 10 '15 at 12:25
  • @All - Yes, I am running in strict mode. – Tom Baxter Jul 10 '15 at 12:26
  • @EdCottrell: That's not a duplicate of that question (I know, because I created the linked one) – Felix Kling Jul 10 '15 at 12:26
  • @TomBaxter so there is your answer – Arun P Johny Jul 10 '15 at 12:26
  • 1
    just updated my answer Re: chrome giving window in stead of undefined, seems it works find in a sef rather then entered into the console – atmd Jul 10 '15 at 12:27
  • @ArunPJohny I'm running this on console, `'use strict' alert(this); // alerts as [object Window] -- Okay function p1() { //console.log('p1', this); alert(this); } var p2 = function () { // console.log('p2', this); alert(this); } p1(); // alerts as undefined -- ??? p2(); // alerts as undefined -- ?? window.p1(); // alerts as [object Window] -- Okay window.p2(); // alerts as [object Window] -- Okay` doesn't alert "undefined", but on fiddler, it does – Sudhansu Choudhary Jul 10 '15 at 12:29
  • @SudhansuChoudhary http://stackoverflow.com/questions/11677452/possible-to-enable-strict-mode-in-firebug-and-chromes-console & http://stackoverflow.com/questions/24369328/how-to-use-strict-mode-in-chrome-javascript-console – Arun P Johny Jul 10 '15 at 12:31
  • @ArunPJohny thanks for those links. – Sudhansu Choudhary Jul 10 '15 at 12:42

3 Answers3

3

Becasue you are using strict mode and as per the spec:

If this is evaluated within strict mode code, then the this value is not coerced to an object.

The code you have does alert window in all instances of alert, but because you are in strict mode, it is undefined (as it should be)

UPDATE: chrome dev tools alerts window not undefined, however if you wrap it in a self executing function you get undefined as expected

(function(){
   'use strict';
   alert(this);
}());
atmd
  • 7,430
  • 2
  • 33
  • 64
  • Thanks for the clarification. I agree on chrome console (dev tools) it doesn't alert "undefined". Got me confused! – Sudhansu Choudhary Jul 10 '15 at 12:33
  • it confused me to, strange that firefox used the 'use strict' from putting it in the console but chome required a wrapper – atmd Jul 10 '15 at 12:35
2

When you call a function like foo(), then the value of this depends on whether the code runs in strict mode or not (the default actually).

In strict mode, this will be undefined (as you already found out).

In "loose mode" this will indeed refer to window, but that's not because the functions are global, i.e. "owned" by the global scope. You get the same behavior for local functions:

(function() {
  function foo() {
    console.log(this); // logs the window object, but `foo` is not global
  }
  foo();
}());

This is simply an explicitly defined behavior:

  1. If the function code is strict code, set the ThisBinding to thisArg.
  2. Else if thisArg is null or undefined, set the ThisBinding to the global object.
  3. Else if Type(thisArg) is not Object, set the ThisBinding to ToObject(thisArg). ...

As you can see, in "loose" mode, if thisArg is undefined, which is the case if you call the function "normally" as foo(), then it will be set to window explicitly.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

this is what denotes you are referring to that object you are. It is mostly used in Object Oriented Programming to differentiate between an object's self versus input variables.

Example (pseudo code):

var1 //instance variable of object void Constructor(var1){ this.var1 = var1 }

What this describes is the constructor takes in a var called var1, and sets it's own variable var1 to it.

In your case, I would assume that when in a function:

function p1() { alert(this); }

being called as p1();, it is not strictly in an object context, therefore this does not mean anything. By calling it from the window's context window.p1();, you are making the window object call the function, therefore giving this a value.

Snappawapa
  • 1,697
  • 3
  • 20
  • 42
  • sorry but thats incorrect. the issue is cause by strict mode. in the examples p1() and window.p1() are the same thing, strict mode is whats effecting the value of `this` – atmd Jul 10 '15 at 12:32