1

I just learned this way of initializing a variable in javascript:

var MyGlobalVar = {
    Property1 : 1,
    Property2 : "Two"
}

Which is pretty neat because is a lot like a static object. But is there any way I can run initialization code inside it, kinda like a static constructor would do?

How about using eval, such as Property1 : eval("[code to run here...]");?

I just don't want to put any initialization or part of my object's definition outside the object itself (outside the brackets).

Edit: My initialization code would actually return a filled up array, so Property2 would be this array. But I don't want to recreate this array every time is needed.

2
  • "kinda like a static constructor would do" So why not just use a constructor? Commented Nov 26, 2011 at 19:37
  • If you don't want to re-create the array every time then the array should just be a global, or namespaced global--there's no reason to run or eval anything. Commented Nov 26, 2011 at 19:56

4 Answers 4

4

If I understood what you want:

var MyGlobalVar = {
  Property1 : 1,
  Property2 : (function(){ var arr=["this", "is", "an", "array"];return arr; })()
}

Property2 will be an array...you can have any code after that, and whatever you return will be its value.

EDIT: I changed the above code to return an array.

Sign up to request clarification or add additional context in comments.

6 Comments

Ohhh, now I get it. I first though that was returning a function. There are so many hidden details in js.
@jsoldi, the function only runs once. It is defined, called, and forever lost all in the same expression.
@jsoldi: ok, I edited the code to return an array...is that what you need?
Yea, well actually I'll create it in a loop but I already got the point. I'll accept this answer as soon as I can.
Sorry, had to accept answer above. Is a more flexible solution (I can use this and stuff like that) I didn't know about and what I ended up using.
|
2

If you want a constructor, why not use a constructor?

var MyGlobalVar = new function() {
      // run whatever code you want in here

      // The new object being constructed is referenced via "this"
    this.Property1 = 1;
    this.Property2 = "Two";
};

This code uses an anonymous function as the constructor. You can run whatever code you want inside. The new object is referenced by this, and it is returned automatically, so MyGlobalVar will look like:

{
    Property1: 1,
    Property2: "Two"
}

Another approach, and one that is perhaps more common than using an anonymous constructor, is to use a module pattern. It is very similar, but it doesn't use the function as a constructor by calling it with new, and it just returns an object literal.

The above code would be rewritten like this:

var MyGlobalVar = (function() {
      // run whatever code you want in here

      // The new object is an object literal that we create and return
    var _new_obj = {
        Property1: 1,
        Property2: "Two"
    };

    return _new_obj;
})();

Just like the first example, it gives you an enclosed environment where you can run whatever code you need in creating the values to be referenced by your object.

The end result is practically identical. The only real difference is that the prototype chain of the object in the first example looks like:

_new_obj ---> {} ---> Object.prototype ---> null

whereas the prototype chain in the new version looks like:

_new_obj ---> Object.prototype ---> null

So there's a slightly shorter chain. It won't make such a difference that you should base any decision on it.

3 Comments

You're right. I didn't know you can create and define an object at the same time this way (I previously defined them and then created them like var myObject = new MyClass()).
Why would people use the other way of creating objects on the fly when you can do it this way?
@jsoldi: If you don't need to run any more code in the initialization, then it would just be simpler to use an object literal like you have in the question. It may be a little faster in some some browsers too. If you need some construction, then a constructor is nice. Another approach is a module pattern that is very similar, but invokes a function without new and returns an object literal that was built inside. I'll update my answer with an example since it is worth knowing about.
2

Rather than use eval, you could run an immediate function:

var v = {
    prop1: function() { 
        // whatever 
        return aResult;
    }()
}

Or a previously-defined function:

function foo() {
    // whatever
    return aResult;
}

var v = {
    prop1: foo(),
}

Best to avoid eval if not strictly needed.

Comments

2

If you really want everything inside the object, you can run a function which you also define inside the object literal, which does the following:

  • runs initialization stuff
  • returns the value that the property should have

Something like:

var data = {
    prop: (function() {
              // init
              return "foo";
          })(),

    prop2: (function() {
               // init
               return "bar";
           })()
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.