0

This way doesn't work:

var myObj = {
  name : 'luke',
  age : '24',
  myFunc: (function() {
    console.log(this.name); //returns nothing 
  }())
};

If I use this:

var myObj = {
  name : 'luke',
  age : '24',
  myFunc: (function() {
    console.log(myObj.name); //it works
  }())
};

What makes 'this' fail in the first example on line 5?

ActionON
  • 96
  • 1
  • 8
  • this is referring to the outside scope since that is a self-executing function and `myObj` doesn't have a value. – Daniel A. White Oct 03 '15 at 20:45
  • You misunderstood what `this` does. See [How does the “this” keyword work?](http://stackoverflow.com/q/3127429/1529630) for an explanation. – Oriol Oct 03 '15 at 20:48

2 Answers2

1

The value of this is set by the Javascript interpreter based on how a function is called, NOT on how it is declared.

In this case, you are calling the function as just a normal function so this will be set to either the global object (which is window in a browser) or to undefined (in strict mode).

This part of your declaration:

(function() {
    console.log(this.name); //returns nothing 
}())

is just a normal IIFE function call so thus this is set to window or undefined (if in strict mode).

See this answer for a complete description of the five different ways that this can be controlled by the calling code.

In addition, your myFunc property ends up undefined because you have an IIFE as the value, but that IIFE does not return anything so the return value is undefined thus the resulting value of the myFunc property is undefined.


Since you seem to be having a hard time understand how your IIFE works, your code here:

var myObj = {
  name : 'luke',
  age : '24',
  myFunc: (function() {
    console.log(this.name); //returns nothing 
  }())
};

evaluates the same as this:

function aFunc() {
    console.log(this.name);
}

var myObj = {
  name : 'luke',
  age : '24',
  myFunc: aFunc()
};

And, from this, you should be able to see that aFunc() is a normal function call which causes Javascript to set this inside that function to either window or undefined (if in strict mode).

Community
  • 1
  • 1
jfriend00
  • 580,699
  • 78
  • 809
  • 825
  • what if I put it inside another function? – ActionON Oct 03 '15 at 20:57
  • @ActionON - it depends only upon how the function is called. Read the answer I linked to - it should explain it all. – jfriend00 Oct 03 '15 at 21:06
  • I read the answer you linked. I'm still confused as to why the IIFE isn't considered a method of the object, and instead an outside function in the global scope? – ActionON Oct 03 '15 at 22:00
  • @ActionON - the IIFE is its own function call and it's just a plain function call. There's no `obj.method()` function call there that would cause `this` to be set to `obj`. – jfriend00 Oct 03 '15 at 22:01
  • It is set to be a property of myObj so when I try to call this.Name, I think this.Name refers to the object scope and not the global scope. What is wrong with my way of thinking? What makes an IIFE evaluate to the global scope, because if I remove the IIFE and just make a function and call it, this.name() then it works. Why does this refer to the window? – ActionON Oct 03 '15 at 22:27
  • @ActionON - I've now said it three times and pointed you to a post that says it the fourth time. An IIFE is a regular function call as in `func()`. ALL regular function calls set `this` to either `window` or to `undefined` (if in strict mode). There's nothing else to it. The only difference with the IIFE is that the function is inline and anonymous, but it's still just a regular function call. We still have no idea what you're trying to actually accomplish because as the end of my answer says, even if your IIFE worked as intended, your `myFunc` property would still be undefined. – jfriend00 Oct 03 '15 at 22:30
  • Nvm, I think the answer is because I use console.log(this.Name) and so this refers to the scope of console which is window. I was trying to figure out why it was evaluating to window's scope. – ActionON Oct 03 '15 at 22:51
  • @ActionON - no, that has nothing to do with it. I can't really say any more. If you want `this` to be set to your object, then your function has to be called as `obj.method()` or using `.call()` or `.apply()`, Do you get how your IIFE is just called as a regular with just `(function(){})()`. And, ALL regular function calls set `this` to the global object or `undefined` (if in strict mode). That's what is happening here. – jfriend00 Oct 03 '15 at 22:54
  • Thanks, that cleared up the confusion @jfriend00 quite a bit. Still confused about some things but I will learn it later. – ActionON Oct 03 '15 at 23:06
1

Because during the below code declaration

myFunc: (function() {
    console.log(this.name); //returns nothing 
}())

this will be pointing to window object.

If you replace the above block by removing .name

myFunc: (function() {
    console.log(this); //Outputs window object on the console.
}())

Also either way, they are self-executed functions, they are not returning any value, only thing is while defining the object, you can see the console output from them. If you execute the first one, you can see window.name, in the second one window object in the console output.

rajuGT
  • 5,784
  • 2
  • 22
  • 43