375

Is "var" optional?

myObj = 1;

same as ?

var myObj = 1;

I found they both work from my test, I assume var is optional. Is that right?

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
Ray Lu
  • 26,208
  • 12
  • 60
  • 59
  • 28
    "Optional" is perhaps an unfortunate choice of words, as `var` is optional in the sense that an assignment statement can be successfully interpreted with or without it, but not optional in the case where you want to explicitly declare a variable in local scope. – D'Arcy Rittich Mar 21 '10 at 01:25
  • 6
    Check out this Fiddle: http://jsfiddle.net/GWr6Z/2/ – Milk Man Jun 10 '14 at 18:21
  • 1
    One other difference nobody mentioned: `console.out(var myObj=1)` doesn't work, but `console.out(myObj=1)` outputs 1. See my answer (currently at the very bottom) – Codebling Jul 15 '15 at 01:35

14 Answers14

595

They mean different things. If you use var the variable is declared within the scope you are in (e.g. of the function). If you don't use var, the variable bubbles up through the layers of scope until it encounters a variable by the given name or the global object (window, if you are doing it in the browser), where it then attaches. It is then very similar to a global variable. However, it can still be deleted with delete (most likely by someone else's code who also failed to use var). If you use var in the global scope, the variable is truly global and cannot be deleted.

This is, in my opinion, one of the most dangerous issues with javascript, and should be deprecated, or at least raise warnings over warnings. The reason is, it's easy to forget var and have by accident a common variable name bound to the global object. This produces weird and difficult to debug behavior.

Bruno Bronosky
  • 66,273
  • 12
  • 162
  • 149
Stefano Borini
  • 138,652
  • 96
  • 297
  • 431
  • You can create a variable inside a method without using `var`. That doesn't make it global, IE does that often, how can that be dangerous? – Buhake Sindi Mar 21 '10 at 01:15
  • @The Elite Gentleman: Wrong. It does. – SLaks Mar 21 '10 at 01:18
  • 1
    @The Elite Gentleman: Yes, it does make it a global variable. – PatrikAkerstrand Mar 21 '10 at 01:18
  • 15
    @codemeit : javascript is full of pitfalls like this, but all in all it's a beautiful and very pleasant language. Don't hate it. Just know the pitfalls and leave them out of your code. – Stefano Borini Mar 21 '10 at 01:25
  • 12
    Automatic global variables are removed from ECMAScript 5 strict mode, which is basically an implicit deprecation. Hopefully implementations will give a warning if you forget `var` in non-strict mode. – Matthew Crumley Mar 21 '10 at 01:48
  • 47
    Actually no, assigning to a variable without using `var` does not make it *global*. It causes JS to traverse up the scope chain, eventually ending up at the global object if the variable was not used anywhere before. If the variable *was* declared using `var` somewhere before global, that's the scope that will be used. It's also an integral part of how JS works and what makes it really powerful, so I wouldn't describe it as a "pitfall". – deceze Mar 21 '10 at 04:01
  • 36
    @deceze: traversing up the scope chain is a good thing, but adding it to the global scope if it doesn't find anything is a pitfall. – Matthew Crumley Mar 24 '10 at 18:08
  • @TheEliteGentleman If you were right, that would mean that different browsers interpreted the absence of var differently. How can you then NOT think that omitting var is dangerous? If your claim were right, you would be even more wrong. – Bruno Bronosky Sep 21 '12 at 07:39
  • Delete is actually a little funky across browsers (IE and safari specifically do things differently). It's *not* for variables, it's for properties. var foo = 1 is a declaration, which sets it's dont_delete flag to true. bar = 1 is a blind assignment, which does not set it's dont_delete flag. bar = 1 will create a global ONLY if it there is nothing named bar in the scope chain between where it's assigned and the global object. – Steve Kallestad Apr 13 '13 at 12:32
  • It says here on the [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Values,_variables,_and_literals?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FValues%2C_variables%2C_and_literals) that it always declares global variables if `var` is not used and **also** JS will generate strict warning. However, [it](http://jsfiddle.net/2nSHs/) doesn't. – Sid Aug 27 '13 at 03:48
  • Simple, just don't forget to use var. That's like forgetting a $ in php. Or do like I do, and use an IDE that color codes those non-var variables differently. I like this feature, it makes things in js easier and cleaner. – Captain Hypertext Dec 30 '15 at 01:10
  • @Sid It won't generate a warning if you're not in strict mode. – gcampbell Jul 08 '16 at 10:13
  • When it bubbles up through the scope until it finds a similarly named variable, is it bubbling up through the call stack? I.e. in one file, I have `function1`, which declared and used a variable. At some point, some of the functionality was scoped out into a helper function, `function2`. The use of the variable was moved, but the declaration was still in `function1`. So `function1` and `function2` are declared in the same file scope, and `function1` calls `function2`. Does this un-declared var in `function2` bubble up to `function1`'s scope, or does it go to file scope and up from there? – Jake T. Jul 11 '18 at 17:59
  • I just noticed this due to recently updating both node and VSCode, not sure which led to this behavior, but now unused variables are greyed out. So, this variable I'm talking about is greyed out in `function1`, and used without declaration in `function2`. But from the sounds of it, the `function1` scope declaration should catch the `function2`'s use, so it seems misleadingly greyed out in my editor. – Jake T. Jul 11 '18 at 18:03
  • When it comes to JS, `console.log()` is your friend. Or, some type of debugger tools in your text editor. It's critical to write just a little bit of code at a time and keep testing it in some fashion. – CodeFinity Oct 03 '18 at 23:16
143

This is one of the tricky parts of Javascript, but also one of its core features. A variable declared with var "begins its life" right where you declare it. If you leave out the var, it's like you're talking about a variable that you have used before.

var foo = 'first time use';
foo = 'second time use';

With regards to scope, it is not true that variables automatically become global. Rather, Javascript will traverse up the scope chain to see if you have used the variable before. If it finds an instance of a variable of the same name used before, it'll use that and whatever scope it was declared in. If it doesn't encounter the variable anywhere it'll eventually hit the global object (window in a browser) and will attach the variable to it.

var foo = "I'm global";
var bar = "So am I";

function () {
    var foo = "I'm local, the previous 'foo' didn't notice a thing";
    var baz = "I'm local, too";

    function () {
        var foo = "I'm even more local, all three 'foos' have different values";
        baz = "I just changed 'baz' one scope higher, but it's still not global";
        bar = "I just changed the global 'bar' variable";
        xyz = "I just created a new global variable";
    }
}

This behavior is really powerful when used with nested functions and callbacks. Learning about what functions are and how scope works is the most important thing in Javascript.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • 17
    This is really the best answer because knowing the actual behavior of the scope chain is key to understanding how functional Javascript works -- even if you don't prefer to code in a functional style it is very nice to know considering how many commonly used libraries *do* use a functional style. – marta.joed Jul 10 '12 at 18:43
  • Isn't `var foo = 1` moved to the top of the current function scope, and not right where you declare it? `foo = 100;` `bar = 200;` `(function fooBarDeluxeEdition() {` `bar = 300;` `//var bar = 400; // try uncommenting this for fun! :)` `}());` `document.write(bar);` – carlsb3rg Jan 29 '14 at 12:48
  • 1
    @carl The statement itself is not moved to the top, no. Essentially, a `var` statement reserves the variable name within the current scope, and it will start out with an `undefined` value. The assignment of the initial value will only happen exactly where you wrote `var .. = ..`. – deceze Jan 29 '14 at 13:17
  • @deceze Yeah, I was a bit quick off the mark. My point was that the answer (tho good otherwise) states that the variable begins its life at the `var` statement. But in reality, if I'm not mistaken, all `var` statements are scanned before the function scope is executed so all the variables are "born" at the start of the scope even though they are assigned at the `var`. It might be contrived, but my example shows a scenario where you could be scratching your head for a while (especially if you are a lover of multi-page functions). – carlsb3rg Jan 30 '14 at 11:57
  • 1
    @carl Well, fair enough, sort of. It *"begins its life in the scope"*. Does that fit better? :) – deceze Jan 30 '14 at 12:45
  • Actually your example is very misleading. `xyz` will never become a global variable because you never call the internal function and there is no way to call it from outside. – Dmitry Nov 08 '17 at 21:06
  • This is the best answer, that wiped away in 2 lines my longest confusion. Thank you @deceze. I appreciate it. – lazyList Jun 25 '18 at 02:37
  • @FLAW “wbu”? Anyway, yes, hoisting exists. But this here is more about nested scopes and in which scope the variable “begins its life”. Hoisting is another separate concept to consider, but out of scope for this answer. – deceze Jul 04 '21 at 06:09
82

Nope, they are not equivalent.

With myObj = 1; you are using a global variable.

The latter declaration create a variable local to the scope you are using.

Try the following code to understand the differences:

external = 5;
function firsttry() {
  var external = 6;
  alert("first Try: " + external);
}

function secondtry() {
  external = 7;
  alert("second Try: " + external);
}

alert(external); // Prints 5
firsttry(); // Prints 6
alert(external); // Prints 5
secondtry(); // Prints 7
alert(external); // Prints 7

The second function alters the value of the global variable "external", but the first function doesn't.

lietus
  • 199
  • 2
  • 11
Eineki
  • 14,773
  • 6
  • 50
  • 59
  • 7
    Be careful saying "you are using a global variable". "myObj = 1;" refers to a variable in an outer scope, which may not be global. Your example, however, does reference (and potentially implicitly declares) a variable in the global scope. – DSoa Dec 13 '13 at 14:56
23

There's a bit more to it than just local vs global. Global variables created with var are different than those created without. Consider this:

var foo = 1; // declared properly
bar = 2; // implied global
window.baz = 3; // global via window object

Based on the answers so far, these global variables, foo, bar, and baz are all equivalent. This is not the case. Global variables made with var are (correctly) assigned the internal [[DontDelete]] property, such that they cannot be deleted.

delete foo; // false
delete bar; // true
delete baz; // true

foo; // 1
bar; // ReferenceError
baz; // ReferenceError

This is why you should always use var, even for global variables.

bcherry
  • 7,150
  • 2
  • 28
  • 37
17

There's so much confusion around this subject, and none of the existing answers cover everything clearly and directly. Here are some examples with comments inline.

//this is a declaration
var foo;

//this is an assignment
bar = 3;

//this is a declaration and an assignment
var dual = 5;

A declaration sets a DontDelete flag. An assignment does not.

A declaration ties that variable to the current scope.

A variable assigned but not declared will look for a scope to attach itself to. That means it will traverse up the food-chain of scope until a variable with the same name is found. If none is found, it will be attached to the top-level scope (which is commonly referred to as global).

function example(){
  //is a member of the scope defined by the function example
  var foo;

  //this function is also part of the scope of the function example
  var bar = function(){
     foo = 12; // traverses scope and assigns example.foo to 12
  }
}

function something_different(){
     foo = 15; // traverses scope and assigns global.foo to 15
}

For a very clear description of what is happening, this analysis of the delete function covers variable instantiation and assignment extensively.

Steve Kallestad
  • 3,484
  • 2
  • 23
  • 31
  • "food-chain of scope" => "scope chain" – zeros-and-ones Nov 04 '14 at 22:16
  • I found this to be the most concise explanation and demonstration of the behavior. I know this is old, but it's still valid and I think it could be improved by calling each function followed by a statement of `foo` to show that it causes an error in the first case and has magically been added to the global scope in the second case. If you prefer, I can edit it myself. – KobeJohn Nov 29 '15 at 03:24
16

var is optional. var puts a variable in local scope. If a variable is defined without var, it is in global scope and not deletable.

edit

I thought that the non-deletable part was true at some point in time with a certain environment. I must have dreamed it.

kzh
  • 19,810
  • 13
  • 73
  • 97
  • 3
    Short, but not correct. If it is "defined" as you say without var, you **can** delete it. But not using var does not always declare a new variable, it may reference one in an outer scope. – DSoa Dec 13 '13 at 15:08
9

Check out this Fiddle: http://jsfiddle.net/GWr6Z/2/

function doMe(){

a = "123"; // will be global
var b = "321"; // local to doMe
alert("a:"+a+"  --  b:"+b);

b = "something else"; // still local (not global)
alert("a:"+a+"  --  b:"+b);

};


doMe()
alert("a:"+a+"  --  b:"+b); // `b` will not be defined, check console.log
Milk Man
  • 1,256
  • 13
  • 21
9

They are not the same.

Undeclared variable (without var) are treated as properties of the global object. (Usually the window object, unless you're in a with block)

Variables declared with var are normal local variables, and are not visible outside the function they're declared in. (Note that Javascript does not have block scope)

Update: ECMAScript 2015

let was introduced in ECMAScript 2015 to have block scope.

Dexter
  • 4,036
  • 3
  • 47
  • 55
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
6

The var keyword in Javascript is there for a purpose.

If you declare a variable without the var keyword, like this:

myVar = 100;

It becomes a global variable that can be accessed from any part of your script. If you did not do it intentionally or are not aware of it, it can cause you pain if you re-use the variable name at another place in your javascript.

If you declare the variable with the var keyword, like this:

var myVar = 100;

It is local to the scope ({] - braces, function, file, depending on where you placed it).

This a safer way to treat variables. So unless you are doing it on purpose try to declare variable with the var keyword and not without.

Cyril Gupta
  • 13,505
  • 11
  • 64
  • 87
  • 1
    +1 for "t can cause you pain if you re-use the variable name" – Ray Lu Mar 21 '10 at 01:24
  • Not braces. JavaScript variables are not block-scoped but function-scoped. A var anywhere in a function body is exactly equivalent to a var at the top of the function body. – Denis Howe Oct 31 '13 at 18:52
4

Var doesn't let you, the programmer, declare a variable because Javascript doesn't have variables. Javascript has objects. Var declares a name to an undefined object, explicitly. Assignment assigns a name as a handle to an object that has been given a value.

Using var tells the Javacript interpreter two things:

  1. not to use delegation reverse traversal look up value for the name, instead use this one
  2. not to delete the name

Omission of var tells the Javacript interpreter to use the first-found previous instance of an object with the same name.

Var as a keyword arose from a poor decision by the language designer much in the same way that Javascript as a name arose from a poor decision.

ps. Study the code examples above.

4

Consider this question asked at StackOverflow today:

Simple Javascript question

A good test and a practical example is what happens in the above scenario...
The developer used the name of the JavaScript function in one of his variables.

What's the problem with the code?
The code only works the first time the user clicks the button.

What's the solution?
Add the var keyword before the variable name.

Community
  • 1
  • 1
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
1

Everything about scope aside, they can be used differently.

console.out(var myObj=1);
//SyntaxError: Unexpected token var
console.out(myObj=1);
//1

Something something statement vs expression

Codebling
  • 10,764
  • 2
  • 38
  • 66
0

No, it is not "required", but it might as well be as it can cause major issues down the line if you don't. Not defining a variable with var put that variable inside the scope of the part of the code it's in. If you don't then it isn't contained in that scope and can overwrite previously defined variables with the same name that are outside the scope of the function you are in.

-2

I just found the answer from a forum referred by one of my colleague. If you declare a variable outside a function, it's always global. No matter if you use var keyword or not. But, if you declare the variable inside a function, it has a big difference. Inside a function, if you declare the variable using var keyword, it will be local, but if you declare the variable without var keyword, it will be global. It can overwrite your previously declared variables. - See more at: http://forum.webdeveloperszone.com/question/what-is-the-difference-between-using-var-keyword-or-not-using-var-during-variable-declaration/#sthash.xNnLrwc3.dpuf

Mogsdad
  • 44,709
  • 21
  • 151
  • 275