0

From MDN:

Using with is not recommended, and is forbidden in ECMAScript 5 strict mode. The recommended alternative is to assign the object whose properties you want to access to a temporary variable.

It seems like a great/useful/convenient feature. Why is it frowned upon? What other ways are there to achieve that effect? I don't want to have to go:

veryLongNS.y = veryLongNS.myFunc(veryLongNS.x);
veryLongNS.z = 6;
veryLongNS.otherFunc();
veryLongNS.a = {
    a:1,
    b:2,
    c:veryLongNS.processThree(3)
};
Joseph
  • 117,725
  • 30
  • 181
  • 234
wwaawaw
  • 6,867
  • 9
  • 32
  • 42

1 Answers1

5

Here's a related answer: Are there legitimate uses for JavaScript's "with" statement?

Also: http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/

How about the following as an alternative?

(function(obj) {
    obj.y = obj.myFunc(obj.x);
    obj.z = 6;
    obj.otherFunc();
    obj.a = {a:1,b:2,c:obj.processThree(3)};
})(myAwkwardlyNamedObjectToBeUsedAsANameSpaceThatIWishToModifyAndNotJustRead);

Edit: For clarity and posterity, this is also possible (and in most cases would be preferred over the above -- I wouldn't recommend doing it in the global scope, but I wouldn't recommend doing anything in the global scope):

function someFunction() {
    // in some function
    var obj = myAwkwardlyNamedObjectToBeUsedAsANameSpaceThatIWishToModifyAndNotJustRead;
    obj.y = obj.myFunc(obj.x);
    obj.z = 6;
    obj.otherFunc();
    obj.a = {a:1,b:2,c:obj.processThree(3)};
    // ... any other stuff in the function
}
Community
  • 1
  • 1
Nathan Wall
  • 6,426
  • 2
  • 22
  • 23
  • +1 for the link to the other question alone. However, I'd just use a "simple alias" in most cases: `var x = someLongNameOrExpressions; x.y = ..` –  Sep 12 '12 at 04:48
  • Man, do I love the ability to take complex constructs and fold them down to `ns` with the blink of an immediately-invoked function. Aliasing is perfect, most of the time... ...but when it's not, knowing how to do this (and why it works) adds such simplicity and power to what you want to accomplish. – Norguard Sep 12 '12 at 04:52
  • 1
    Sure, I'm in agreeance @pst. I would use an alias in most situations as well. The point is the IIFE is the closest equivalent to `with` in terms of "I want to use this variable here but make it easier please; then I don't want to access it down there under this block, so clean up the part that made it easier." – Nathan Wall Sep 12 '12 at 04:55
  • Okay, but doesn't that prevent you from modifying the `AwkwardlyNamedObject`? IE, once your IIFE ends, won't any modifications made to `obj` be lost while `myAwkwardlyNamedObjectToBeUsedAsANameSpaceThatIWishToModifyAndNotJustRead` remains untouched? – wwaawaw Sep 12 '12 at 05:41
  • @NathanWall also, where does the "clean up the part that made it easier" part fit in with the aliasing approach? Would you just `alias = undefined;` when you're done using the `alias` `var`? – wwaawaw Sep 12 '12 at 05:42
  • Changes made to `obj` will also be made to `Awkward...` Since they're references to the same object, anything changed on one will changed on the other also. – Nathan Wall Sep 12 '12 at 05:59
  • As to your second question, sure you could do that, but in most situations you'd probably be working in a limited, short-lived scope, in a function, and wouldn't really need to clean up an alias if taking that approach. Just stop using it and let the function exit. – Nathan Wall Sep 12 '12 at 06:00
  • @NathanWall really??!?! you just blew my mind! If that's the case, then how does one "close" a variable's value into another independent variable that can get modified in the future without phasing the original? Is there a way to do it without `new`? – wwaawaw Sep 15 '12 at 13:31
  • (1) We're really talking about changes to *Objects* here not variables. One object can just have two names. It could be named variable `x` in one place and variable `y` in another, but be the same object. The same with people right? I was a teacher for a while, and my students called me Mr. Wall. My friends call me Nathan. If something changes about Nathan, it also changes about Mr. Wall. You can't give Nathan a haircut without giving Mr. Wall a haircut. They're the same person, just with different names. The same thing is going on here. – Nathan Wall Sep 15 '12 at 15:03
  • (2) So if you want to change `x`'s properties and not have it affect `y`'s properties, they need to be different objects. You could make a copy of `x` and store it in `y`, and then they're different (but similar objects). If I was cloned and my clone was named Ted, then Ted could get a haircut and Nathan could still have long hair, right? If you have a library it's easy to make a copy of an object. In jQuery you could use `$.extend`. – Nathan Wall Sep 15 '12 at 15:07
  • @NathanWall _"you'd probably be working in a limited, short-lived scope, in a function"_ Are there any other types of scopes aside from global scope and functional scope? – wwaawaw Sep 22 '12 at 11:34
  • sorry, that was a typo up there -- i meant "'clone'", not "'close'" – wwaawaw Sep 22 '12 at 11:36
  • Cool, great explanations. Thanks!! How could you clone an object in native, plain-vanilla JS, though? – wwaawaw Sep 22 '12 at 11:37