The with
construction allows the use of an arbitrary object for the scope.
In modern JavaScript, this construction was abandoned, in strict mode it does not work, but it can still be found in the old code.
Syntax:
Any reference to the variable inside with
first looks for it among the properties of obj
, and only then - outside of with
.
Example
In the example below, the variable will not be taken from the global domain, but from obj
:
Let's try to get a variable that is not in obj
:
Here, the interpreter first checks for the presence of obj.b
, does not find it, and goes outside with
.
Especially funny is the use of nested with
:
Properties from different objects are used as ordinary variables ... Magic! The search order of variables in the selected code: size => obj => window
Variable changes
When using with
, as in nested functions, the variable changes in the area where it was found.
For example:
Why abandoned with
?
There are several reasons.
- In the modern standard,
JavaScript
abandoned with
because the with
construction is error-prone and opaque. Problems arise when a variable is assigned in with(obj)
, which is intended to be in the properties of obj
, but not there.
For example:
In line (2)
assigned a property that is missing in obj
. As a result, the interpreter, not finding it, creates a new global variable window.size
.
Such errors are rare, but very difficult to debug, especially if the size
has changed not in a window
, but somewhere in an external LexicalEnvironment
.
- Another reason - JavaScript compression algorithms do not like
with
. Javascript is compressed before displaying on server. There are many tools for this, such as Closure Compiler and UglifyJS. In short, they either compress the code with
with errors, or leave it partially uncompressed. - And finally, performance - complicating the search for a variable due to
with
entails additional overhead . Modern engines use many internal optimizations, some of which cannot be applied to code that has with
. Here, for example, run this code in a modern browser. The performance of the fast
function is significantly different slow
with an empty (!) with
. And the point here is with
, because the presence of this design impedes optimization.
Replacement with
Instead of with
it is recommended to use a temporary variable, for example:
This is not so elegant, but it removes an extra level of nesting and it is absolutely clear what will happen and where properties will be assigned to.
Total
- The
with(obj) { ... }
construct uses obj
as an additional scope. All variables accessed inside the block are first searched in obj
. - The
with
design is deprecated and not recommended for a number of reasons. Avoid her.
Importance: 5
The second ( 2
), because when accessing any variable inside with
- it is searched first of all in the object.
Accordingly, 2
will be displayed:
[Open task in new window]
Importance: 5
Displays 3
.
The with
construction does not create scopes; only functions create it. Therefore, the var b
declaration inside the construct also works as if it were outside it.
The code in the problem is equivalent to this:
Comments
To leave a comment
Scripting client side JavaScript, jqvery, BackBone
Terms: Scripting client side JavaScript, jqvery, BackBone