javascript中的“with”关键字

“with” keyword in javascript

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Are there legitimate uses for JavaScript’s “with” statement?

我最近发现在javascript中,可以执行以下操作:

1
2
3
4
with document{
    write('foo');
    body.scrollTop = x;
}

这样做的缺点是需要检查每个变量以查看它是否属于文档对象,从而产生显着的开销。

或者,可以做这样的事情:

1
2
3
var d = document;
d.write('foo');
d.body.scrollTop = x;

是否有任何情况下使用'with'关键字是合理的?


只是不要使用它:
http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/

JavaScript's with statement was intended to provide a shorthand for writing recurring accesses to objects. So instead of writing

1
2
ooo.eee.oo.ah_ah.ting.tang.walla.walla.bing = true;
ooo.eee.oo.ah_ah.ting.tang.walla.walla.bang = true;

You can write

1
2
3
4
with (ooo.eee.oo.ah_ah.ting.tang.walla.walla) {
    bing = true;
    bang = true;
}

That looks a lot nicer. Except for one thing. There is no way that you can tell by looking at the code which bing and bang will get modifed. Will ooo.eee.oo.ah_ah.ting.tang.walla.walla be modified? Or will the global variables bing and bang get clobbered? It is impossible to know for sure...

If you can't read a program and be confident that you know what it is going to do, you can't have confidence that it is going to work correctly. For this reason, the with statement should be avoided...


尽管几乎在所有地方都有相反的建议,但我认为有"with"的用途。例如,我正在研究Javascript的域模型框架,它使用下划线字符,就像jQuery使用"$"一样。这意味着如果没有"with",我会在代码中散布许多下划线,这些下划线会降低其可读性。这是使用框架的应用程序的随机行:

1
_.People().sort(_.score(_.isa(_.Parent)),'Surname','Forename');

而"with"则看起来像

1
2
3
4
5
6
7
with (_) {
    ...

    People().sort(score(isa(Parent)),'Surname','Forename');

    ...
}

真正有用的是"with"的只读版本。


我会避免在生产代码中使用它,因为它含糊不清但是通过使用with模仿let绑定有一个替代解决for-loop-closure解决方案,这里是我以前的答案的副本:

使用for循环内部函数的标准闭包解决方案的替代方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
blah
blah
foo

    (function() {
    var anchors = document.getElementsByTagName('a');
        for ( var i = anchors.length; i--; ) {
            var link = anchors[i];
            with ({ number: i }) {
                link.onclick = function() {
                    alert(number);
                };
            }
        }
    })();

感谢nlogax提供了一个我几乎被扯掉的解决方案:
Javascript臭名昭着的循环问题?

这是标准解决方案:

1
2
3
4
5
6
7
8
9
10
11
    (function() {
    var anchors = document.getElementsByTagName('a');
    for ( var i = anchors.length; i--; ) {
        var link = anchors[i];
        (function(i) {
            link.onclick = function() {
                alert(i)
            }
        })(i);
    }
    })();