Javascript - with

> (World Wide) Web - (W3|WWW) > Javascript (Js|ECMAScript) > ECMAScript - Grammar Standard

1 - About

with permits to call a number of methods in sequence on a single object without having to repeat it.

The with construct conforms to the Scope chain. Therefore, the arguments of the object function will be looked up first in the object itself and after that in the prototype.

If the object acquire later an new property that conflicts with a variable in its scope, it will not choose anymore the variable in its scope but its local variable. This is why it's not a recommended construct. The behavior is is unpredictable. And unpredictable behaviors are bad for optimizing compilers.

See the below example “scope problem” for an illustration.

3 - Example

3.1 - Property Access

var obj = {
	foo: 1,
	bar: 2,
	baz: 3
};
 
// Object access pattern
obj.foo = 4;
obj.bar = 5;
obj.baz = 6;
 
// with an "easier" short-hand
with (obj) {
	foo = 7;
	bar = 8;
	baz = 9;
}

3.2 - Scope problem

3.2.1 - Scope chain

This example illustrates the Scope chain problem with the with construct.

The argument of a function may conflict with the property of the object of its prototype.

pointProto = {
    x:0,
    y:0,
    color:"black"
};
 
function Point () {
    var x;
    var y;
    var color;
    this.setX = function(x) { this.x = x };
    this.setY = function(y) { this.y = y };
    this.setColor = function(color) { this.color = color };
};
 
Point.prototype = pointProto;
 
function coloredOrigin(color) {
    var point = new Point();
    with (point) {
        setX(0);
        setY(0);
        setColor(color)
   }
   return point;
}
console.log("You would expect from the below expression to return the color 'yellow' but \n"+
  "it will return the color 'black' from the prototype");
console.log(coloredOrigin("yellow").color);

Advertising

3.2.2 - New property problem

If the object acquires a property that conflicts with a function argument, the behavior of this function will be to use that property instead of the function argument.

function Point () {
    var x;
    var y;
    var color;
    this.setX = function(x) { this.x = x };
    this.setY = function(y) { this.y = y };
    this.setColor = function(color) { this.color = color };
};
 
 
function coloredOrigin(col) {
    var point = new Point();
    with (point) {
        setX(0);
        setY(0);
        setColor(col)
   }
   return point;
}
origin = coloredOrigin("yellow");
console.log("The function works as expected. The color property has the 'yellow' value.");
console.log(origin.color);
 
 
console.log("\nIf later we add a property to the object that use the same name, the function will be broken.\n"+
  "Example with the 'col' property that will define a column position. \n"+
  "The 'color' property of a 'coloredOrigin' object will return the column position in place of the color :(" );
Point.prototype = { col: 1 };
origin = coloredOrigin("yellow");
console.log(origin.color);

4 - Documentation / Reference

web/javascript/es/with.txt · Last modified: 2019/02/16 17:40 by gerardnico