views:

115

answers:

4

Is there a sweet way to init an array if not already initilized? Currently the code looks something like:

if (!obj) var obj = [];
obj.push({});

cool would be something like var obj = (obj || []).push({}), but that does not work :-(

+8  A: 

var obj = (obj || []).push({}) doesn't work because push returns the new length of the array. For a new object, it will create obj with value of 1. For an existing object it might raise an error - if obj is a number, it does not have a push function.

You should do OK with:

var obj = obj || [];
obj.push({});
Kobi
gnarf
@gnarf - Interesting idea. If I understand correctly, the line should still start with `var obj = `.
Kobi
+1  A: 

The best I can think of is:

var obj; 
(obj = (obj || [])).push({});
RoToRa
except implicitly, `obj` *should* always be undefined in this case, which makes the `(obj || [])` just `[]`
gnarf
No it won't. `var obj;` won't set `obj` to `undefined` if it was `defined` before.
RoToRa
Unless you are using `var obj` twice in the same scope, which just seems like a waste of the `var` to me...
gnarf
A: 
with(obj = obj || []) push({});
MooGoo
I think your pre-edit was superior: `(obj || [{}])` is functional.
annakata
-1: erk! never ever *ever* use the "with" feature of Javascript.
Spudley
I fear to use the `with` statement as Douglas Crockford told me (http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/) that bad unforseen things can happen on its usage
sod
@annakata unfortunatly the pre-edit would only add `{}` to the array if it didn't already exist, and leave it as is otherwise. I realized this shortly after I posted. @Spudley - please explain why its usage is harmful in this case. @sod - and what bad unforeseen things could possibly happen with this simple line of code? There is no ambiguity at all.
MooGoo
+1 to counter the with-hate: `with` is a powerful tool whether crockford likes it or not, it's just a matter of understanding the tool *as is everything else*. A good coder knows when to break rules.
annakata
@MooGoo - ah, subtle - I read the OP as wanting exactly that, but you're right it could go either way. Well that's a much more boring question now :)
annakata
Spudley, sod: a better rule would be to read the articles of influential people carefully and then think about it for yourself before making your mind up. Crockford or anyone else saying that `with` is evil evil evil does not make it true.
Tim Down
A: 

Just a tiny tweak to your idea to make it work

var obj = (obj || []).concat([{}]);
Peter Bailey
Although, `concat` actually returns a completely new array... Meaning if obj was already defined (which i'm still curious how that might happen), it will not have the `{}` added to it in any parent scope...
gnarf
That's true, but there's no scope information in the original question. Also, since he's using an assignment statement in his attempt, mutation clearly isn't a requirement.
Peter Bailey
His original seems to state: `obj` should either stay as it is, or become an empty array, then `push` something onto it... The problem being that `push` wouldn't happen on the original `obj` so if that `obj` was a reference to a different array, or a function parameter, etc... your code would not do the same thing...
gnarf
The code in the accepted answer refutes the point you're trying to make. `obj.push()` executes no matter what the original state of `obj` is
Peter Bailey