stackunderflow
stackunderflow

Reputation: 1714

NodeJS anonymous function within an object

Why does the following not return `a and b'?

Staff.config = {
    a: 'a constant',
    b: (function(){
        return this.a + ' and b';
    })()
};

console.log(Staff.config) // { a: 'a constant', b: 'undefined and b' }

Upvotes: 0

Views: 756

Answers (2)

Endre Simo
Endre Simo

Reputation: 11551

The reason you got an undefined is related to where the object properties are hoisted. First you are trying to reference an object property which is not yet allocated in the memory, so Javascript cannot point to a memory address, because that memory address is not yet allocated. This is the reason why you are getting an undefined on

return this.a + ' and b';

Here this is referencing to the window object, which is a global object. In Javascript each object is extended from the global Object or window in the case if Javascript is running in a browser.

Second you are trying to invoke a function by using the Self Invoking method, but this is always running in it's own scope, which means you cannot access a variable outside of it's own scope, at least if you do not wrap it to it's own context. Something like:

(function(closer) {
//...
})(scope)

This is what is called a closure.

So back to your original problem. If you construct your object in the following way it will work. This is because you are referring to properties of already instantiated object.

var Staff = Staff || {};

Staff.config = function() {
  this.a = "a constant";
  this.b = this.a + " and b";    
}

var staff = new Staff.config();
console.log(staff);

Upvotes: 0

Rayon
Rayon

Reputation: 36609

(function(){ return this.a + ' and b'; })() is getting executed under the global scope(this refers to window in browser) and in your case, global context does not have property a hence it is undefined.

Easier solution would be using function expression as a value of b hence Staff.config.b() will return expected output.

var Staff = {};
Staff.config = {
  a: 'a constant',
  b: function() {
    return this.a + ' and b';
  }
};
alert(Staff.config.b());

You could achieve the same using getter which gets the value of a specific property

Try this:

var Staff = {};
Staff.config = {
  a: 'a constant',
  get b() {
    return this.a + ' and b';
  }
};
alert(Staff.config.b);

Upvotes: 1

Related Questions