Javascript: z = z || [] throws an error if VAR is not used - why?

Out of purely intellectual curiosity why javascript takes

var z = z || []; 

to initialize z (since z can be determined initially)

but without var, it throws an error (in global space)

 z = z || []; 

(if z was previously undefined)

In a global environment, you do not need to use VAR, although I understand that this can be bad practice.

Before you say this is a duplicate of issues such as

What is the purpose of the var keyword and when to use it (or omit it)?

Pay attention to the announcement in which "If you are in a global area, then there is no difference."

Obviously, not 100% true, given my working example.

Is this a quirk or is there legitimate logic?


Adding a summary of the answer, as I recognized it:

Thanks to Tim (see below), the key to my misunderstanding did not understand this (fundamental from javascript)

var z; does nothing if z already exists

The way this expression seems to have it in both directions, if you're wrong, suppose that "var z" is always initialized.

Starting on the left side, "var z" simply ensures that z is defined, but does not actually affect the existing value if it already exists. Then on the right, if z already exists, it is used, if not, the variable was just declared (but empty), so it will not be used, but it will not throw an error.

This is a great article about this kind of overview and upgrade in Javascript: http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

Many thanks to the minitech and to all who contributed!

+7
source share
3 answers

z = z || [] z = z || [] will call any region (global or not) where there are no z in the chain of regions. The reason for this is that the expression first tries to get the value of an existing variable named z on the right side, which is an error when it does not exist.

The reason var z = z || [] var z = z || [] does not cause an error, it is that the variable z is created before the expression (if it does not already exist), an effect known as rising.

On the other hand, assigning a value to an unresolved identifier (for example, z = 2 ) will work without errors in any area (except for strict ECMAScript 5 mode, which prohibits and throws it). If the identifier cannot be resolved, it will be added as a property of the final object in the scope chain, which is a global object, which gives the appearance of creating a global variable.

+6
source

The effect is correct. var will always declare its "operands" immediately, while you do not declare it, your script tries to use the undefined variable and throws an error.

If you are in a global scope, you can assign a nonexistent variable, and it will have the same effect as declaring it, for example, bad practice. Of course, in your case it is undefined. In this case, although it may be due to intellectual curiosity, you will never write

 var z = z || []; 

because there is no point in doing it. Rather, you can do:

 if(!window.z) { window.z = []; } 

. In fact, when I declare things in a global scope (it never ;) ), I use window. something window. something because it makes my intentions clearer.

+10
source

You can assign an undeclared variable z = 123 ; however, you cannot try to read what z = z || [] z = z || [] .

+4
source

All Articles