Are there legitimate uses for JavaScript's “wi

2018-12-31 06:13发布

Alan Storm's comments in response to my answer regarding the with statement got me thinking. I've seldom found a reason to use this particular language feature, and had never given much thought to how it might cause trouble. Now, I'm curious as to how I might make effective use of with, while avoiding its pitfalls.

Where have you found the with statement useful?

30条回答
只若初见
2楼-- · 2018-12-31 06:54

I just really don't see how using the with is any more readable than just typing object.member. I don't think it's any less readable, but I don't think it's any more readable either.

Like lassevk said, I can definitely see how using with would be more error prone than just using the very explicit "object.member" syntax.

查看更多
有味是清欢
3楼-- · 2018-12-31 06:54

It's good for putting code that runs in a relatively complicated environment into a container: I use it to make a local binding for "window" and such to run code meant for a web browser.

查看更多
流年柔荑漫光年
4楼-- · 2018-12-31 06:58

I don't ever use with, don't see a reason to, and don't recommend it.

The problem with with is that it prevents numerous lexical optimizations an ECMAScript implementation can perform. Given the rise of fast JIT-based engines, this issue will probably become even more important in the near future.

It might look like with allows for cleaner constructs (when, say, introducing a new scope instead of a common anonymous function wrapper or replacing verbose aliasing), but it's really not worth it. Besides a decreased performance, there's always a danger of assigning to a property of a wrong object (when property is not found on an object in injected scope) and perhaps erroneously introducing global variables. IIRC, latter issue is the one that motivated Crockford to recommend to avoid with.

查看更多
琉璃瓶的回忆
5楼-- · 2018-12-31 06:59

Having experience with Delphi, I would say that using with should be a last-resort size optimization, possibly performed by some kind of javascript minimizer algorithm with access to static code analysis to verify its safety.

The scoping problems you can get into with liberal use of the with statement can be a royal pain in the a** and I wouldn't want anyone to experience a debugging session to figure out what the he.. is going on in your code, only to find out that it captured an object member or the wrong local variable, instead of your global or outer scope variable which you intended.

The VB with statement is better, in that it needs the dots to disambiguate the scoping, but the Delphi with statement is a loaded gun with a hairtrigger, and it looks to me as though the javascript one is similar enough to warrant the same warning.

查看更多
墨雨无痕
6楼-- · 2018-12-31 06:59

Yes, yes and yes. There is a very legitimate use. Watch:

with (document.getElementById("blah").style) {
    background = "black";
    color = "blue";
    border = "1px solid green";
}

Basically any other DOM or CSS hooks are fantastic uses of with. It's not like "CloneNode" will be undefined and go back to the global scope unless you went out of your way and decided to make it possible.

Crockford's speed complaint is that a new context is created by with. Contexts are generally expensive. I agree. But if you just created a div and don't have some framework on hand for setting your css and need to set up 15 or so CSS properties by hand, then creating a context will probably be cheaper then variable creation and 15 dereferences:

var element = document.createElement("div"),
    elementStyle = element.style;

elementStyle.fontWeight = "bold";
elementStyle.fontSize = "1.5em";
elementStyle.color = "#55d";
elementStyle.marginLeft = "2px";

etc...

查看更多
裙下三千臣
7楼-- · 2018-12-31 07:00

CoffeeScript's Coco fork has a with keyword, but it simply sets this (also writable as @ in CoffeeScript/Coco) to the target object within the block. This removes ambiguity and achieves ES5 strict mode compliance:

with long.object.reference
  @a = 'foo'
  bar = @b
查看更多
登录 后发表回答