let 块语句和等效的 with 语句有什么区别?

发布于 2024-11-17 00:20:04 字数 677 浏览 4 评论 0原文

已过时

let 语句的块版本在最终确定之前已从 ES6 中删除,并且已从支持它的浏览器中删除。这个问题现在只具有历史意义。

使用 ECMAScript 6 let 块语句 并使用带有等效对象字面量的 with 语句?

使用 let 语句

var x = 10;
let (x = x * 10,
     y = x + 5) {
    console.log("x is " + x + ", y is " + y);
}

使用 with 语句

var x = 10;
with ({x: x * 10,
       y: x + 5}) {
    console.log("x is " + x + ", y is " + y);
    // writes "x is 100, y is 15"
}

OBSOLETE

The block version of the let statement was dropped from ES6 before it was finalized, and it has been removed from the browsers that supported it. This question is now only of historic interest.

Is there any difference between using an ECMAScript 6 let block statement and using a with statement with an equivalent object literal?

using let statement

var x = 10;
let (x = x * 10,
     y = x + 5) {
    console.log("x is " + x + ", y is " + y);
}

using with statement

var x = 10;
with ({x: x * 10,
       y: x + 5}) {
    console.log("x is " + x + ", y is " + y);
    // writes "x is 100, y is 15"
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

各自安好 2024-11-24 00:20:04

您可以同时使用 withlet 语句来实现相同的目标,但我发现这里有两个显着差异。最后,let 语句是 with 语句的新版本,消除了后者的缺点。

性能:对于 with 语句,您可以向作用域链添加一个额外的 JavaScript 对象。这不是一个小成本,你必须记住,对象有一个可能很长的原型链,因此要查找变量,JavaScript 引擎首先必须搜索该对象及其所有原型。另一方面,对于 let 语句,引擎最多只需要搜索一个附加对象。 let 语句确实可以在没有任何开销的情况下实现,因为 let 语句中声明的所有变量在编译时都是已知的,并且 JavaScript 引擎可以轻松优化代码,例如,通过本质上将您的示例视为:

var x = 10;
var let1x = x * 10;
var let1y = x + 5;
{
    console.log("x is " + let1x + ", y is " + let1y);
}

代码可读性:如上所述,let语句始终使所有声明在编译时可见,这可以防止这样的代码:

with (foo)
{
    console.log("x is " + x + ", y is " + y);
}

如果你看看上面的代码,什么是x,什么是是吗?它们是函数变量还是对象 foo 的属性?如果不知道 foo 是什么,您就无法告诉它 - 并且对于同一函数的不同调用,它可能会有所不同。这是 with 语句被弃用的主要原因。虽然您可以按照您在问题中所做的方式使用它(这很好),但它也允许非常有问题且不可读的代码结构。 let 语句则不然——灵活性较低有时反而是一种优势。

You can use both with and let statements to achieve the same goal but I see two significant differences here. In the end, the let statement is a new revision of the with statement with the disadvantages of the latter removed.

Performance: In case of the with statement you add an additional JavaScript object to the scope chain. This isn't a small cost, you have to remember that objects have a potentially long prototype chain and so to look up a variable the JavaScript engine first has to search the object and all its prototypes. On the other hand, for a let statement the engine only needs to search at most one additional object. The let statement can indeed be implemented without any overhead at all, since all the variables declared in a let statement are known at compile time and the JavaScript engine can easily optimize the code, e.g. by essentially treating your example like:

var x = 10;
var let1x = x * 10;
var let1y = x + 5;
{
    console.log("x is " + let1x + ", y is " + let1y);
}

Code readability: As already mentioned above, a let statement always makes all declarations visible at compile time, this prevents code like this:

with (foo)
{
    console.log("x is " + x + ", y is " + y);
}

If you look at the code above, what is x and what is y? Are they function variables or properties of the object foo? You cannot tell it without knowing what foo is - and it might be different for different calls of the same function. Which is the main reason the with statement has been deprecated. While you can use it the way you've done in your question (and that is fine), it also allows very questionable and unreadable code constructs. The let statement doesn't - less flexibility is sometimes an advantage.

凡尘雨 2024-11-24 00:20:04

我能想到的最好的办法是 with 也会泄漏 Object 原型的任何属性:

with ({x: 10}) {
    hasOwnProperty = 3;
    console.log(hasOwnProperty);  // 3
}
console.log(hasOwnProperty);  // [native code]; this is window.hasOwnProperty

在实践中不太可能成为问题,但仍然是一个潜在的陷阱。

我还怀疑 with 比词法稍慢,因为它添加了另一个必须搜索的名称空间。

老实说,我只是避免这两种结构; with 风格的隐式属性访问不太适合我,如果我真的需要这样一个严格的范围,那么内部带有 let 表达式的裸块读起来不会那么尴尬。一个 let 块。

The best I can come up with is that with will also leak any property of the Object prototype:

with ({x: 10}) {
    hasOwnProperty = 3;
    console.log(hasOwnProperty);  // 3
}
console.log(hasOwnProperty);  // [native code]; this is window.hasOwnProperty

Unlikely to be a problem in practice, but still a potential gotcha.

I also suspect that with is slightly slower than lexicals, since it adds another namespace that has to be searched.

Honestly, I'd just avoid both constructs; with-style implicit property access doesn't sit well with me, and if I really need a tight scope like that, a bare block with let expressions inside reads less awkwardly than a let block.

第几種人 2024-11-24 00:20:04

以下是每个语句的不同范围规则。

和:

with 语句使得对命名引用的访问效率低下,因为此类访问的范围要到运行时才能计算

with 语句使得对命名引用的访问效率低下,因为在运行时let

使用let定义的变量的范围是let块本身,以及其中包含的任何内部块,除非这些块定义了相同名称的变量。

let 语句是非标准的,而 with 语句在严格模式下不可用。

参考文献

Here are the different scoping rules for each statement.

with:

the with statement makes access to named references inefficient, because the scopes for such access cannot be computed until runtime

let:

The scope of variables defined using let is the let block itself, as well as any inner blocks contained inside it, unless those blocks define variables by the same names.

The let statement is non-standard, while the with statement is unavailable in Strict Mode.

References

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文