0

I use an object literal to collect various DOM elements I add dynamically because I want to be able to reference them by variable (code below is simplified, there would be much more, like events and so on):

ui = {
  header : $('<div id="header"></div>').appendTo('body').css('color','#009'),
  footer : $('<div id="footer"></div>').appendTo('body').css('color','#990')
}

Now I wish I could just add other objects to this, but it will throw an error:

ui = {
  header : $('<div id="header"></div>').appendTo('body').css('color','#009'),
  footer : $('<div id="footer"></div>').appendTo('body').css('color','#990'),
  headerSpecial : $('<span>some header</span>').appendTo(ui.header) // this line will cause an error "ui is not defined"
}

I suppose this is because until the ui object is closed, I can't reference anything inside yet. SO I would have to separate out these things into separate objects. But is there some way I can do it all in a single object? Should I wrap some stuff in anonymous functions and then call them?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
tim
  • 3,823
  • 5
  • 34
  • 39
  • 2
    JSON is a *string representation* of data that just so happens to resemble a JavaScript object. What you have is a JavaScript object literal, nothing to do whatsoever with JSON. – gen_Eric Apr 11 '13 at 22:12
  • 2
    Your thought is correct. `ui.header` doesn't exist yet when you are trying to ser `headerSpecial`. – gen_Eric Apr 11 '13 at 22:13
  • I agree with Rocket. I don't think the misunderstanding of JSON is the cause of this problem, although that will be an important distinction when tim fixes the first problem and gets to the point of trying to do string operations with something that is not a string. – AaronLS Apr 11 '13 at 22:14
  • 1
    I edited my title and question to remove JSON reference. thanks for the clarification. – tim Apr 11 '13 at 22:25
  • Well, I've over time come into the habit of writing all my scripts more or less in a style that I first learned when studying JSON. I guess JSON is only flat data. I'm always creating my vars as objects and if useful, I collect those inside an array for easier referencing. – tim Apr 15 '13 at 22:38

2 Answers2

5

It is no problem to use one and the same object to hold the references, but you cannot use self references in one and the same literal expression. Do it in two steps:

// create the object
ui = {
  header : $('<div id="header"></div>').appendTo('body').css('color','#009'),
  footer : $('<div id="footer"></div>').appendTo('body').css('color','#990')
}

// add a new property to the object
ui.headerSpecial = $('<span>some header</span>').appendTo(ui.header);
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • yes I knew that, which is why I outlined that thought in the question ,which is: is there a way to do it INSIDE the object literal? – tim Apr 11 '13 at 22:24
  • 1
    To be fair, you said *" But is there some way i can do it all in a single object?"*. This is one object. The short answer to whether this can be done with one literal is: no, not directly. The longer answer is here: http://stackoverflow.com/a/4616273/218196. If that's what you actually wanted to know, we can close this question as duplicate of the other one. – Felix Kling Apr 11 '13 at 22:25
  • I really like zzzzBovs solution. This gets me what I really want, and reminded me can treat functions as variables too. – tim Apr 15 '13 at 22:41
2

Rather than using an object literal, why not instantiate an anonymous function?

ui = new function () {
    this.header = $('<div id="header"></div>').appendTo('body').css('color','#009');
    this.footer = $('<div id="footer"></div>').appendTo('body').css('color','#990');
    this.headerSpecial = $('<span>some header</span>').appendTo(this.header);
};
zzzzBov
  • 174,988
  • 54
  • 320
  • 367