loading...

JavaScript – Miscellaneous Statements

This section describes the remaining three JavaScript
statements— with, debugger, and use
strict
.

with

In The Scope Chain, we discussed the scope
chain—a list of objects that are searched, in order, to perform
variable name resolution. The with statement is used to temporarily
extend the scope chain. It has the following syntax:

with (object)
    statement

This statement adds object to the
front of the scope chain, executes
statement, and then restores the scope
chain to its original state.

The with statement is
forbidden in strict mode (see “use strict”) and
should be considered deprecated in non-strict mode: avoid using it
whenever possible. JavaScript code that uses with is difficult to optimize and is
likely to run more slowly than the equivalent code written without
the with statement.

The common use of the with
statement is to make it easier to work with deeply nested object
hierarchies. In client-side JavaScript, for example, you may have to
type expressions like this one to access elements of an HTML
form:

document.forms[0].address.value

If you need to write expressions like this a number of times,
you can use the with statement to
add the form object to the scope chain:

with(document.forms[0]) {
    // Access form elements directly here. For example:
    name.value = "";
    address.value = "";
    email.value = "";
}

This reduces the amount of typing you have to do: you no
longer need to prefix each form property name with document.forms[0]. That object is
temporarily part of the scope chain and is automatically searched
when JavaScript needs to resolve an identifier such as address. It is just as simple, of course,
to avoid the with statement and
write the code above like this:

var f = document.forms[0];
f.name.value = "";
f.address.value = "";
f.email.value = "";

Keep in mind that the scope chain is used only when looking up
identifiers, not when creating new ones. Consider this code:

with(o) x = 1;

If the object o has a
property x, then this code
assigns the value 1 to that
property. But if x is not defined
in o, this code is the same as
x = 1 without the with statement. It assigns to a local or
global variable named x, or
creates a new property of the global object. A with statement provides a shortcut for
reading properties of o, but not
for creating new properties of o.

debugger

The debugger statement
normally does nothing. If, however, a debugger program is available
and is running, then an implementation may (but is not required to)
perform some kind of debugging action. In practice, this statement
acts like a breakpoint: execution of JavaScript code stops and you
can use the debugger to print variables’ values, examine the call
stack, and so on. Suppose, for example, that you are getting an
exception in your function f()
because it is being called with an undefined argument, and you can’t
figure out where this call is coming from. To help you in debugging
this problem, you might alter f()
so that it begins like this:

function f(o) {
  if (o === undefined) debugger;  // Temporary line for debugging purposes
  ...                             // The rest of the function goes here.
}

Now, when f() is called
with no argument, execution will stop, and you can use the debugger
to inspect the call stack and find out where this incorrect call is
coming from.

debugger was formally added
to the language by ECMAScript 5, but it has been implemented by
major browser vendors for quite some time. Note that it is not
enough to have a debugger available: the debugger statement won’t start the
debugger for you. If a debugger is already running, however, this
statement will cause a breakpoint. If you use the Firebug debugging
extension for Firefox, for example, you must have Firebug enabled
for the web page you want to debug in order for the debugger statement to work.

“use strict”

"use strict" is a
directive introduced in ECMAScript 5.
Directives are not statements (but are close enough that "use strict" is documented here). There
are two important differences between the "use strict" directive and regular
statements:

  • It does not include any language keywords: the directive
    is just an expression statement that consists of a special
    string literal (in single or double quotes). JavaScript
    interpreters that do not implement ECMAScript 5 will simply see
    an expression statement with no side effects and will do
    nothing. Future versions of the ECMAScript standard are expected
    to introduce use as a true
    keyword, allowing the quotation marks to be dropped.

  • It can appear only at the start of a script or at the
    start of a function body, before any real statements have
    appeared. It need not be the very first thing in the script or
    function, however: a "use
    strict"
    directive may be followed or preceded by other
    string literal expression statements, and JavaScript
    implementations are allowed to interpret these other string
    literals as implementation-defined directives. String literal
    expression statements that follow the first regular statement in
    a script or function are simply ordinary expression statements;
    they may not be interpreted as directives and they have no
    effect.

The purpose of a "use
strict"
directive is to indicate that the code that
follows (in the script or function) is strict
code
. The top-level (nonfunction) code of a script is
strict code if the script has a "use
strict"
directive. A function body is strict code if it is
defined within strict code or if it has a "use strict" directive. Code passed to the
eval() method is strict code if
eval() is called from strict code
or if the string of code includes a "use
strict"
directive.

Strict code is executed in strict mode.
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 (Variable-Length Argument Lists: The Arguments Object) 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 non-strict 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.)

  • In strict mode, octal integer literals (beginning with a 0
    that is not followed by an x) are not allowed. (In non-strict
    mode, some implementations allow octal literals.)

  • In strict mode, the identifiers eval and arguments are treated like keywords,
    and you are not allowed to change their value. You cannot assign
    a value to these identifiers, declare them as variables, use
    them as function names, use them as function parameter names, or
    use them as the identifier of a catch block.

  • In strict mode, the ability to examine the call stack is
    restricted. arguments.caller
    and arguments.callee both
    throw a TypeError within a strict mode function. Strict mode
    functions also have caller
    and arguments properties that
    throw TypeError when read. (Some implementations define these
    nonstandard properties on non-strict functions.)

Comments are closed.

loading...