15

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 :-(

4
  • Um... Thats an odd position for var obj.. after if(!obj), doesn't make a lot of sense, is obj also defined in a higher scope or something? Commented Sep 14, 2010 at 13:49
  • javascript does not init an extra scope inside if/else Commented Sep 14, 2010 at 14:09
  • I know this, which is why I'm wondering why you would ever conditionally define a var like that... I'm assuming obj is probably a function parameter, and the keyword var in there is just useless / unwanted... If not, there is no way obj could ever be defined before this call... Try obj={}; (function() { if (!obj) var obj = []; console.log(obj); })(); -- You'll get [] Commented Sep 14, 2010 at 14:28
  • Possible duplicate of Create array and push into it in one line Commented Jul 19, 2016 at 20:04

5 Answers 5

18

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({});
Sign up to request clarification or add additional context in comments.

2 Comments

The sillier one-liner (obj = obj||[]) && obj.push({}) && obj might do what he is looking for...
@gnarf - Interesting idea. If I understand correctly, the line should still start with var obj = .
2

The best I can think of is:

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

3 Comments

except implicitly, obj should always be undefined in this case, which makes the (obj || []) just []
No it won't. var obj; won't set obj to undefined if it was defined before.
Unless you are using var obj twice in the same scope, which just seems like a waste of the var to me...
2

Just a tiny tweak to your idea to make it work

var obj = (obj || []).concat([{}]);

4 Comments

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...
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.
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...
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
0
with(obj = obj || []) push({});

7 Comments

I think your pre-edit was superior: (obj || [{}]) is functional.
-1: erk! never ever ever use the "with" feature of Javascript.
I fear to use the with statement as Douglas Crockford told me (yuiblog.com/blog/2006/04/11/with-statement-considered-harmful) that bad unforseen things can happen on its usage
@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.
+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.
|
0

If the variable has already been declared it can be done with nullish coalescing assignment:

(obj ??= []).push({});

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.