JavaScript’s with Statement and Why it's Deprecated
Join the DZone community and get the full member experience.
Join For FreeThis post explains how the with statement works in JavaScript and why its use is discouraged.
Syntax and semantics
Syntax:
with (object)
statement
introduces the properties of object as local variables in statement. Example (the braces are optional for single statements, but it is recommended to add them):
> with({ first: "John" }) { console.log("Hello "+first); }There is one similar case in JavaScript where the properties of an object are turned into variables and that is the global object window. All of its properties are global variables and vice versa. In contrast, variables that are declared in statement are not added to object, but to the surrounding function, where they still exist after leaving the block.
Hello John
> with({}) { var x = "abc"; } > x 'abc'
The with statement is deprecated
The use of the with statement is generally discouraged. It is forbidden in strict mode:> function foo() { "use strict"; with({}); } SyntaxError: strict mode code may not contain 'with' statementsBest practice: Don’t use a with statement.
with(foo.bar.baz) { console.log("Hello "+first+" "+last); }Do use a temporary variable with a short name.
var b = foo.bar.baz; console.log("Hello "+b.first+" "+b.last);If you don’t want to expose the temporary variable b to the current scope, you can use an IIFE:
(function() { var b = foo.bar.baz; console.log("Hello "+b.first+" "+b.last); }());You also have the option of making the object that you want to access a parameter of the IIFE:
(function(b) { console.log("Hello "+b.first+" "+b.last); }(foo.bar.baz));
The rationale of the deprecation
To understand why with is deprecated, look at the following example and notice how the function’s argument completely changes how it works.function foo(arg) { with(arg) { console.log("arg: "+arg) } }Interaction:
> foo("Hello"); arg: Hello // parameter arg > foo({}); arg: [object Object] // parameter arg > foo({ arg: "Hello" }); arg: Hello // property arg.argThere are thus two problems that the with statement causes:
- Performance: one cannot optimize the access to arg (or to any other variable used inside with), because one cannot predict whether arg will refer to a real variable or to a property inside the with argument. That can change with each call.
- Security: you cannot determine what an identifier refers to by looking at its syntactic surroundings (its lexical environment). According to Brendan Eich that was the actual reason why with was deprecated, not performance considerations. Quoting a tweet of his:
with violates lexical scope, making program analysis (e.g. for security) hard to infeasible.
JavaScript
Opinions expressed by DZone contributors are their own.
Comments