Repeated and Omitted Declarations
It is legal and harmless to declare a variable more than once with the var statement. If the repeated declaration has an initializer, it acts as if it were simply an assignment statement.
JavaScript’s function scope means that all variables declared within a function are visible
throughout the body of the function. Curiously, this means that variables are even
visible before they are declared. This feature of JavaScript is informally known as hoisting:
JavaScript code behaves as if all variable declarations in a function (but not any
associated assignments) are “hoisted” to the top of the function. Consider the following
code:
var scope = "global";
function f() {
console.log(scope); // Prints "undefined", not "global"
var scope = "local"; // Variable initialized here, but defined everywhere
"use strict" is a directive introduced in ECMAScript 5. Directives are not statements
(but are close enough that "use strict" is documented here).
The strict mode of ECMAScript 5 is a restricted
subset of the language that fixes a few important language deficiencies and provides
stronger error checking and increased security. The differences between strict mode
and non-strict mode are the following (the first three are particularly important):
- The with statement is not allowed in strict mode.
- In strict mode, all variables must be declared: a ReferenceError is thrown if you
assign a value to an identifier that is not a declared variable, function, function
parameter, catch clause parameter, or property of the global object. (In non-strict
mode, this implicitly declares a global variable by adding a new property to the
global object.)
- In strict mode, functions invoked as functions (rather than as methods) have a
this value of undefined. (In non-strict mode, functions invoked as functions are
always passed the global object as their this value.) This difference can be used to
determine whether an implementation supports strict mode:
var hasStrictMode = (function() { "use strict"; return this===undefined}());
Also, in strict mode, when a function is invoked with call() or apply(), the this
value is exactly the value passed as the first argument to call() or apply(). (In
nonstrict mode, null and undefined values are replaced with the global object and
non-object values are converted to objects.)
- In strict mode, assignments to nonwritable properties and attempts to create new
properties on nonextensible objects throw a TypeError. (In non-strict mode, these
attempts fail silently.)
- In strict mode, code passed to eval() cannot declare variables or define functions
in the caller’s scope as it can in non-strict mode. Instead, variable and function
definitions live in a new scope created for the eval(). This scope is discarded when
the eval() returns.
- In strict mode, the arguments object (§8.3.2) in a function holds a static copy of
the values passed to the function. In non-strict mode, the arguments object has
“magical” behavior in which elements of the array and named function parameters
both refer to the same value.
- In strict mode, a SyntaxError is thrown if the delete operator is followed by an
unqualified identifier such as a variable, function, or function parameter. (In nonstrict
mode, such a delete expression does nothing and evaluates to false.)
- In strict mode, an attempt to delete a nonconfigurable property throws a
TypeError. (In non-strict mode, the attempt fails and the delete expression evaluates
to false.)
- In strict mode, it is a syntax error for an object literal to define two or more properties
by the same name. (In non-strict mode, no error occurs.)
- In strict mode, it is a syntax error for a function declaration to have two or more
parameters with the same name. (In non-strict mode, no error occurs.)
It is legal and harmless to declare a variable more than once with the var statement. If the repeated declaration has an initializer, it acts as if it were simply an assignment statement.
JavaScript’s function scope means that all variables declared within a function are visible
throughout the body of the function. Curiously, this means that variables are even
visible before they are declared. This feature of JavaScript is informally known as hoisting:
JavaScript code behaves as if all variable declarations in a function (but not any
associated assignments) are “hoisted” to the top of the function. Consider the following
code:
var scope = "global";
function f() {
console.log(scope); // Prints "undefined", not "global"
var scope = "local"; // Variable initialized here, but defined everywhere
"use strict" is a directive introduced in ECMAScript 5. Directives are not statements
(but are close enough that "use strict" is documented here).
The strict mode of ECMAScript 5 is a restricted
subset of the language that fixes a few important language deficiencies and provides
stronger error checking and increased security. The differences between strict mode
and non-strict mode are the following (the first three are particularly important):
- The with statement is not allowed in strict mode.
- In strict mode, all variables must be declared: a ReferenceError is thrown if you
assign a value to an identifier that is not a declared variable, function, function
parameter, catch clause parameter, or property of the global object. (In non-strict
mode, this implicitly declares a global variable by adding a new property to the
global object.)
- In strict mode, functions invoked as functions (rather than as methods) have a
this value of undefined. (In non-strict mode, functions invoked as functions are
always passed the global object as their this value.) This difference can be used to
determine whether an implementation supports strict mode:
var hasStrictMode = (function() { "use strict"; return this===undefined}());
Also, in strict mode, when a function is invoked with call() or apply(), the this
value is exactly the value passed as the first argument to call() or apply(). (In
nonstrict mode, null and undefined values are replaced with the global object and
non-object values are converted to objects.)
- In strict mode, assignments to nonwritable properties and attempts to create new
properties on nonextensible objects throw a TypeError. (In non-strict mode, these
attempts fail silently.)
- In strict mode, code passed to eval() cannot declare variables or define functions
in the caller’s scope as it can in non-strict mode. Instead, variable and function
definitions live in a new scope created for the eval(). This scope is discarded when
the eval() returns.
- In strict mode, the arguments object (§8.3.2) in a function holds a static copy of
the values passed to the function. In non-strict mode, the arguments object has
“magical” behavior in which elements of the array and named function parameters
both refer to the same value.
- In strict mode, a SyntaxError is thrown if the delete operator is followed by an
unqualified identifier such as a variable, function, or function parameter. (In nonstrict
mode, such a delete expression does nothing and evaluates to false.)
- In strict mode, an attempt to delete a nonconfigurable property throws a
TypeError. (In non-strict mode, the attempt fails and the delete expression evaluates
to false.)
- In strict mode, it is a syntax error for an object literal to define two or more properties
by the same name. (In non-strict mode, no error occurs.)
- In strict mode, it is a syntax error for a function declaration to have two or more
parameters with the same name. (In non-strict mode, no error occurs.)