Javascript - with

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.

Example

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;
}

Scope problem

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);

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);

Documentation / Reference





Discover More
Javascript Lexical Environment Scope Chaine
Javascript - (Variable) Scope (Namespace)

Variable scope in Javascript. variable scope is delimited by the function definition, not a the block level A block has the scope of its inner function. As a function is also an object, by generalization,...



Share this page:
Follow us:
Task Runner