Categories
ecmascript-5 javascript keyword

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

1642

NOTE: This question was asked from the viewpoint of ECMAScript version 3 or 5. The answers might become outdated with the introduction of new features in the release of ECMAScript 6.

What exactly is the function of the var keyword in JavaScript, and what is the difference between

var someNumber = 2;
var someFunction = function() { doSomething; }
var someObject = { }
var someObject.someProperty = 5;

and

someNumber = 2;
someFunction = function() { doSomething; }
someObject = { }
someObject.someProperty = 5;

?

When would you use either one, and why/what does it do?

8

  • 6

    When chaining var declarations, does putting a newline after a comma affects the behavior? var x=1, y=2, [return]z=3;

    – Alfabravo

    Nov 20, 2011 at 4:35

  • 6

    Failing to use “var” also leaves you exposed in case the variable name you chose happens to be a previously defined global variable. See my journey of grief here: stackoverflow.com/questions/16704014/…

    May 23, 2013 at 15:49

  • 7

    @Ray Toal’s meloncard blog post (definitely worth a read) has moved to blog.safeshepherd.com/23/how-one-missing-var-ruined-our-launch

    Mar 2, 2014 at 17:57

  • 2

    I’d never imagined a poem could inspire me consideration for a programmatic problem

    Mar 15, 2015 at 8:22

  • 3

    @Gibolt but look at the question date, it’s a kinda unfair summon a 2009 question to tell that. Even though, it’s still valid as in current date for maintainability, there are out there a bunch of not “modern JS” code.

    Mar 16, 2018 at 3:53

1405

If you’re in the global scope then there’s not much difference. Read Kangax’s answer for explanation

If you’re in a function then var will create a local variable, “no var” will look up the scope chain until it finds the variable or hits the global scope (at which point it will create it):

// These are both globals
var foo = 1;
bar = 2;

function()
{
    var foo = 1; // Local
    bar = 2;     // Global

    // Execute an anonymous function
    (function()
    {
        var wibble = 1; // Local
        foo = 2; // Inherits from scope above (creating a closure)
        moo = 3; // Global
    }())
}

If you’re not doing an assignment then you need to use var:

var x; // Declare x

15

  • 34

    Is “not really much difference” == “No Difference”?

    – Alex

    Sep 24, 2009 at 8:56

  • 69

    Well, actually yes, there’s difference 🙂 Whether that difference is important is another question. See my answer further down: stackoverflow.com/questions/1470488/…

    – kangax

    Sep 25, 2009 at 4:11

  • 6

    I think that may be Alex’s point, which is why he’s written it using the “is equal to” operator!

    Sep 13, 2012 at 17:52


  • 19

    It’s like shooting oneself with a railgun… Forget to put a ‘var’ before one’s variable, and end up modifying a variable somewhere in the scope chain… Try convincing a Java/C/Python/etc. developer that JavaScript is worthwhile. Ha! C/C++ pitfalls look nice by contrast. Imagine having to debug JavaScript… And some people do that, of course. And there’s so much code (and not simple code, mind you) written in JavaScript…

    Feb 24, 2013 at 12:33

  • 9

    If you’re in the global scope then there’s no difference. >> there is a difference which is explained in the answer below

    Sep 13, 2013 at 11:39

770

There’s a difference.

var x = 1 declares variable x in current scope (aka execution context). If the declaration appears in a function – a local variable is declared; if it’s in global scope – a global variable is declared.

x = 1, on the other hand, is merely a property assignment. It first tries to resolve x against scope chain. If it finds it anywhere in that scope chain, it performs assignment; if it doesn’t find x, only then does it creates x property on a global object (which is a top level object in a scope chain).

Now, notice that it doesn’t declare a global variable, it creates a global property.

The difference between the two is subtle and might be confusing unless you understand that variable declarations also create properties (only on a Variable Object) and that every property in Javascript (well, ECMAScript) have certain flags that describe their properties – ReadOnly, DontEnum and DontDelete.

Since variable declaration creates property with the DontDelete flag, the difference between var x = 1 and x = 1 (when executed in global scope) is that the former one – variable declaration – creates the DontDelete’able property, and latter one doesn’t. As a consequence, the property created via this implicit assignment can then be deleted from the global object, and the former one – the one created via variable declaration – cannot be deleted.

But this is just theory of course, and in practice there are even more differences between the two, due to various bugs in implementations (such as those from IE).

Hope it all makes sense : )


[Update 2010/12/16]

In ES5 (ECMAScript 5; recently standardized, 5th edition of the language) there’s a so-called “strict mode” — an opt-in language mode, which slightly changes the behavior of undeclared assignments. In strict mode, assignment to an undeclared identifier is a ReferenceError. The rationale for this was to catch accidental assignments, preventing creation of undesired global properties. Some of the newer browsers have already started rolling support for strict mode. See, for example, my compat table.

11

  • If I recall correctly, I think I once found a way to be able to delete a var-declared variable with some eval hack. If I remember the exact trick I’ll post here.

    – Tower

    Jun 30, 2011 at 14:51


  • 3

    @Mageek He might be taking about eval-declared variables which are deletable. I wrote a blog post about this once.

    – kangax

    Jun 20, 2012 at 11:06

  • 1

    Little bit out of topic, but mentioning it here for reference. “let” is very similar to “var” and is supported in Mozilla. The main difference is that the scope of a var variable is the entire enclosing function where as “let” is restricted to its block

    – mac

    Oct 1, 2012 at 11:16

  • @kangax what if the last two lines of Alex’s examples were mixed: var someObject = {} and someObject.someProperty = 5 ? Would someProperty become global, while the object it is a property of remains local?

    Nov 28, 2012 at 0:43

  • 1

    The spec name for what @kangax calls the DontDelete flag is configurable (= false), you can read about this in regards to Object.defineProperty and Object.getOwnPropertyDescriptor

    – Paul S.

    Jan 8, 2014 at 14:55

143

Saying it’s the difference between “local and global” isn’t entirely accurate.

It might be better to think of it as the difference between “local and nearest“. The nearest can surely be global, but that won’t always be the case.

/* global scope */
var local = true;
var global = true;

function outer() {
    /* local scope */
    var local = true;
    var global = false;

    /* nearest scope = outer */
    local = !global;

    function inner() {
        /* nearest scope = outer */
        local = false;
        global = false;

        /* nearest scope = undefined */
        /* defaults to defining a global */
        public = global;
    }
}

3

  • 4

    Isn’t the nearest scope outer where you define var global = false;?

    – Snekse

    Apr 19, 2013 at 13:33

  • 1

    @Snekse: ‘nearest’ doesn’t apply when <code>var global = false;</code> is declared. In that declaration, ‘global’ is placed in the scope of outer() because ‘var’ is used in the declaration. Because ‘var’ is not used in inner(), it will change the value in the next level up, which is outer().

    – Mitch

    Sep 18, 2015 at 2:56


  • 1

    I wonder if you comment would change if you changed that line to var global = local; in which case the nears scope of local would be the “local” outer scope that is actively being defined. Though it gets strange if you would change that same line to var global = global in which case the nearest scope when searching for the value of global would be up a level at the global window scope.

    – Snekse

    Sep 23, 2015 at 22:34