19

过时的

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

使用ECMAScript 6let块语句和使用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"
}
4

3 回答 3

8

您可以同时使用withandlet语句来实现相同的目标,但我在这里看到了两个显着差异。最后,该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和什么是y?它们是对象的函数变量还是属性foo?如果不知道是什么,您就无法说出它foo- 对于同一函数的不同调用,它可能会有所不同。with这是该声明已被弃用的主要原因。虽然您可以按照您在问题中所做的方式使用它(这很好),但它也允许非常有问题和不可读的代码结构。该let声明没有 - 较少的灵活性有时是一个优势。

于 2011-07-04T13:07:55.920 回答
7

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

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

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

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

老实说,我只是避免这两种结构;with-style 隐式属性访问不适合我,如果我真的需要像这样的紧凑范围,那么let内部带有表达式的裸块读取起来比let块更尴尬。

于 2011-06-29T00:55:43.063 回答
1

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

和:

with 语句使对命名引用的访问效率低下,因为这种访问的范围直到运行时才能计算出来

让:

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

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

参考

于 2014-05-08T20:23:08.257 回答