9

I know that usage of the with-statement is not recommended in Javascript and is forbidden in ECMAScript 5, but it allows one to create some nice DSLs in Javascript.

For example CoffeeKup-templating engine and the Zappa web DSL. Those uses some very weird scoping methods with the with-statement to achieve DSLish feeling to them.

Is there any future with the with-statement and these kinds of DSLs?

Can this DSL-effect be achieved without the with-statement?

esamatti
  • 18,293
  • 11
  • 75
  • 82

4 Answers4

10

In coffeescript, there is a nice trick to keep using fancy dsls without using with:

 using = (ob, fn) -> fn.apply(ob)

 html = 
   head : (obj) -> # implementation
   body : (fn)  -> # implementation
   div  : (str) -> # implementation

 using html, ->
   @head
     title: "My title"
   @body =>
     @div "foo bar"
     @div "qux moo"

 /*
   in pure javascript you'd be using
   with(html){
     head({title:"My title"});
     body(function(){
       div("foo bar");
       div("qux moo");
     });
   }
 */
Adrien
  • 9,551
  • 3
  • 26
  • 27
  • 1
    Ah, awesome! This is almost as clean as the with-trick. Anyone yet implemented a templating engine using this? – esamatti Mar 21 '11 at 07:03
  • 1
    Don't think so, however it should be possible to adapt coffeekup (https://github.com/mauricemach/coffeekup) to that effect. – Adrien Mar 21 '11 at 07:05
  • 1
    This is not the same as what "with" does. "with" puts variables directly in scope, not as properties of "this". – koops Apr 01 '13 at 22:58
9

with being "forbidden" in ECMAScript 5 is a common misconception.

Only in strict mode of ECMAScript 5 — which is opt-in, mind you — with statement is a syntax error. So you can certainly still use with in fully ECMAScript 5 -compliant implementations, as long as they occur in non-strict (or sloppy, as Crockford calls it) code. It won't be pretty for performance (since mere presence of with often kills various optimizations in modern engines) but it will work.

Future versions of ECMAScript are very likely to be based on strict mode behavior, although will also likely be opt-in as well. So conforming to strict mode is certainly a good idea when it comes to future proofing your scripts.

Tim Down
  • 318,141
  • 75
  • 454
  • 536
kangax
  • 38,898
  • 13
  • 99
  • 135
2

Why not just assign a var to point to the object instead of using with?

'with' style:

with(a_long_object_name_that_is_bloated) {
  propertyA = 'moo';
  propertyB = 'cow';
}

'var' style:

var o = a_long_object_name_that_is_bloated;
o.propertyA = 'moo';
o.propertyB = 'cow';
DanBUK
  • 41
  • 1
1

To answer Epeli's question, take a look at CoffeeMugg which does what CoffeeKup does but using Adrien's technique. It uses this. instead of the with statement.

esamatti
  • 18,293
  • 11
  • 75
  • 82
Jae Kwon
  • 91
  • 5