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

18 javascript language-features let with-statement ecmascript-6

已过时

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);
}
Run Code Online (Sandbox Code Playgroud)

使用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"
}
Run Code Online (Sandbox Code Playgroud)

Wla*_*ant 8

您可以使用both 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);
}
Run Code Online (Sandbox Code Playgroud)

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

with (foo)
{
    console.log("x is " + x + ", y is " + y);
}
Run Code Online (Sandbox Code Playgroud)

如果你看一下上面的代码,那是x什么和什么是y什么?它们是函数变量或对象的属性foo吗?你不能在不知道什么foo是它的情况下告诉它- 并且对于相同功能的不同调用可能会有所不同.这是该with声明被弃用的主要原因.虽然你可以按照你在问题中的方式使用它(这很好),但它也允许非常有问题和不可读的代码构造.该let声明没有-灵活性较差,有时一个优势.


Eev*_*vee 7

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

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

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

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

老实说,我只是避免这两种结构; with-style隐式属性访问并不适合我,如果我真的需要一个像这样的紧凑范围,let内部表达式的裸块读取不如let块的笨拙.