JavaScript binding
JavaScript variables are untyped, so you can assign and re-assign values of any type.
Assignment of a primitive value copies the value; assignment of an object type copies the reference.
Variables are declared with var
, or more recently, with let
and const
. var
has function scope, or else global scope; let
and const
have block scope only.
In non-strict mode, assigning a value to an undeclared variable in the global scope — e.g., x = 'foo'
, where no variable x
has been declared with var
, let
, or const
in the global scope — creates a variable in the global scope. This is easy to do accidentally. If you do it deliberately, you have created a property of the global object. (Unlike a declared variable, it can be deleted using delete
.)
Shadowing and the scope chain
Inside the local scope of a function, declaring a variable with the same name as a variable in the enclosing scope hides the variable in the enclosing scope:
> var x = 1
> function f() { var x = 2; return x; } // hides global variable `x`
> f()
2
Evaluation follows the scope chain up to the global scope. Understanding this is essential to using with
and function closures.
Hoisting
Variables declared in the local scope of a function are hoisted to the top of a function, where they are visible before being bound to their values:
> var x = 1
> function f() {
... console.log(x); // global `x` hidden; local `x` visible, unbound
... var x = 2;
... console.log(x); // local `x` is now bound
... }
> f()
undefined
2
The hoisted equivalent of
function f() {
console.log(x);
var x = 2;
console.log(x);
}
is thus:
function f() {
var x;
console.log(x);
x = 2;
console.log(x);
}
References
Flanagan, David. Javascript: The Definitive Guide. 6th ed, O’Reilly, 2011.