Without the with statement

The with statement is a powerful programming concept that Microsoft added to JScript because it was already in VB and VBScript. It later became part of ECMAScript because one of the major players had it.

The with statement allows you to reference fields in an object without prefixing the field.

var x = 100;
document.body.style.left = x + "px";

Can be written using with:

var x = 100;
with (document.body.style) {
   left = x + "px";
}

This might look good on paper but this feature was designed for compiled languages where the with statement can be handled in the compile step and the running code would just work without any penalties. However, JS is dynamic and interpreted language and therefore the with statement becomes a series of test to test the existence of different fields.

The semantics of the above with statement becomes something like this:

var x = 100;
var $tmp = document.body.style;
if ("left" in $tmp) {
   if ("x" in $tmp) {
      $tmp.left = $tmp.x + "px";
   } else {
      $tmp.left = x + "px";
   }
} else {
   if ("x" in $tmp) {
      left = $tmp.x + "px";
   } else {
      left = x + "px";
   }
}

And this is only for a case where there are 2 references within one with statement. As a matter of fact the worst case scenario for a with statement is O(n*m) where n is the number of nested with statements and m is the number of variables/references in it.

So how do you get around this without having to write the same fields over and over again? Simple. Just use local variables.

5 comments

  1. José Jeria

    I really enjoy these tips. Keep it up!

  2. The main problem with the with statement is that it introduces another scope. Scoping issues are big time in JavaScript and are the cause of a lot of mistakes.

  3. I was mostly considering performance reasons. I totally agree that the with statement makes code harder to read and maintain.

  4. The VB version of With, which uses an unambiguous syntax (a leading dot), seems to address both the efficiency and readability of the code. I wonder why this approach wasn’t used for JScript.

  5. It is never an issue with compiled languages because it is decided at compile time. It is for dynamic/interpreted languages the problems show up.

Comments are closed.