3

I do know that in javascript, when you use "this" keyword inside a function, then "this" would refer to the 'owner' of that function according to Quirksmode website. Therefore when we have a function and we use "this" inside it, then "this" refers to the global (window) object.

I am a little confused on how "this" works, for example in the code below, "this" then should be able to resolve x since x is pretty much a property of global object (in this case window). But this.x in this case alerts "undefined" instead of the x value.

var x = "Global";

function foo(){
    alert(this.x);   //undefined     
};
foo();

I then tried some other things too:

function bar(){
    function foo(){
        alert(this); //[Object DOMWindow]
    };
    foo();
};

bar();

If my understanding is correct, then 'this' should refer to bar() in that second case since it is the owner of foo(), but why is that it instead still refers to the global object?

Can someone explain what is the correct theory regarding "this" keyword?

Benny Tjia
  • 4,872
  • 10
  • 36
  • 47
  • Possible duplicate of http://stackoverflow.com/questions/3127429/javascript-this-keyword – Alex Churchill Aug 07 '11 at 07:52
  • 1
    Also possible duplicate of http://stackoverflow.com/questions/133973/how-does-this-keyword-work-within-a-javascript-object-literal where the first answer is probably the detailed response you want. – Alex Churchill Aug 07 '11 at 07:53
  • @alex c: Not really. Please re-read the question again :) – Benny Tjia Aug 07 '11 at 07:57
  • @BennyTija, in your first example, how are you calling `foo`?? If you are calling it as `foo();` and your code isn't on strict mode, `this` should refer to the global object... Also, are you sure your code is being executed outside any function?? If your code is somehow wrapped in a function (e.g. an event handler), the `var x` declaration obviously won't be made on the global scope... – Christian C. Salvadó Aug 07 '11 at 08:00
  • @CMS: glad to see you're online. Hopefully you can shed a light on this. Please see the edit. You;re right I am calling it as foo() so this should refer to global object. – Benny Tjia Aug 07 '11 at 08:04
  • 1
    @BennyTija, I saw your edit, it doesn't make sense, `this` should refer to the global object, the only way I think where `this.x` could be `undefined`, is as I was telling you, in the case that the variable declaration of `x` was made inside another function. Check the two following examples: [1](http://jsfiddle.net/KVbHr/) and [2](http://jsfiddle.net/KVbHr/1), it's exactly the same code, the difference is that the second one, the code is wrapped in an *onload* handler, so the `x` variable doesn't exist in the global scope... – Christian C. Salvadó Aug 07 '11 at 08:11
  • @CMS: yeah..I think your last sentence is the answer then. It seems that everything makes sense now. CMS, if you just put your comment as answer, then I will upvote+mark it as accepted. Thanks again for the explanation! – Benny Tjia Aug 07 '11 at 08:24

4 Answers4

6

You've got the wrong end of the stick. The value of this depends on how the function is called, not how it is defined.

  • If you call window.foo() then (inside foo) this will be window
  • If you call bar.foo() then this will be bar (although you need to copy foo so it is a property of bar first)
  • If you call baz.bar.foo() then this will be bar (you only ever get the parent object via this)
  • If you call foo.call(bar) then this will also be bar as call lets you override this
  • If you call new foo() then this will be the new object being created

The default object is window, so if you just call foo() then that is the same as window.foo().

It doesn't matter what scope the function is defined in.

Quentin
  • 800,325
  • 104
  • 1,079
  • 1,205
  • @Quentin: Right, however, the invocation of foo() on the first example is clearly done where 'this' currently refers to the window, in this case your first bullet point. But why can;t it resolve its own property using this.x? As we know, x is a property of window(the parent object of foo). – Benny Tjia Aug 07 '11 at 08:14
  • It can. I just copy/pasted the code and it alerted `Global`. Perhaps you are experiencing [this problem](http://stackoverflow.com/questions/6971543/whats-wrong-with-this-code-in-jsfiddle/6971551#6971551) – Quentin Aug 07 '11 at 08:16
2

Summarizing your question, you ask why in your first snippet, this.x is undefined:

var x = "Global";
function foo(){
    alert(this.x);   //undefined     
}
foo();

It doesn't make sense at all, the this value should refer to the global object -if your code were on strict mode, you would get a TypeError, since this by itself would be undefined-.

The only way I think where this.x could be undefined, is in the case that the variable declaration of x was made within a function.

Check the two following examples: 1 and 2, it's exactly the same code, the difference is that the second one, the code is wrapped in an onload event handler, so the x variable doesn't exist in the global scope (window.x is undefined)...

Christian C. Salvadó
  • 723,813
  • 173
  • 899
  • 828
0

Yes, this is always the owner of the function being executed and the best answer about this subject is more than you ever wanted to know about this

var x = "Global";

function foo(){
    alert(this.x); // alerts "Global" for me    
};

As for the bar(), it is a standalone function and this will be bound to the "global" object as described in the answer linked above, which is your case is the DOMWindow

Community
  • 1
  • 1
andyb
  • 42,062
  • 11
  • 113
  • 146
  • 1
    i do know that. but how do you explain the first piece of code? the 'this' is the owner of foo(), and it means it is the window. x belongs to the global object, which is the window. But why does this.x alerts undefined? – Benny Tjia Aug 07 '11 at 07:54
  • 1
    "*always*" is overstating just a bit. `var example = foo.exampleFunc; example();` Now, it's clear that the function is a property of `foo`. Conceptually, `foo` (or its prototype) *owns* it. But when the function is called, `this` will be set to `window` instead. – cHao Aug 07 '11 at 08:51
  • Can you tell me why do we have to use this in when we want some method of object to access that object property, why can't like in case of global object 'this' keyword is not necessary, why can't same happen in case of other objects, I am little confused – Suraj Jain Jul 27 '17 at 04:30
  • @SurajJain do you mean accessing [object properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) because that is different question. It might be better to ask a new question if you have a specific problem. – andyb Aug 21 '17 at 05:21
0

If you really wish to learn how this works, then read the ECMAscript 262 specs from the section 10.3 Execution Context and onwards.

Here is what it says in section 10.4.3:

10.4.3 Entering Function Code

The following steps are performed when control enters the execution context for function code contained in function object F, a caller provided thisArg, and a caller provided argumentsList:

  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) .

  4. Else set the ThisBinding to thisArg.

  5. Let localEnv be the result of calling NewDeclarativeEnvironment passing the value of the [[Scope]] internal property of F as the argument.

  6. Set the LexicalEnvironment to localEnv.

  7. Set the VariableEnvironment to localEnv.

  8. Let code be the value of F‘s [[Code]] internal property.

  9. Perform Declaration Binding Instantiation using the function code code and argumentsList as described in 10.5.

Martin Jespersen
  • 23,663
  • 6
  • 52
  • 66
  • When entering *Function Code*, if you read carefully, the `this` value is *already provided*, here, the value might change if the function is *not-strict* and `this` is primitive, but if you **really** want to know how the `this` value is determined, read [11.2.3 Function Calls](http://es5.github.com/#x11.2.3) and read about the [Reference Specification Type](http://es5.github.com/#x8.7)... – Christian C. Salvadó Aug 07 '11 at 08:45