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

时间:2011-06-26 14:48:11

标签: javascript language-features with-statement let ecmascript-6

  

过时

     

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

使用ECMAScript 6 let block statement和使用等效对象文字的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"
}

3 个答案:

答案 0 :(得分:8)

您可以使用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是什么,y是什么?它们是对象foo的函数变量或属性吗?如果不知道foo是什么,你就无法告诉它 - 对于同一函数的不同调用它可能会有所不同。这是with语句被弃用的主要原因。虽然你可以按照你在问题中的方式使用它(这很好),但它也允许非常有问题和不可读的代码构造。 let声明没有 - 灵活性有时是一个优势。

答案 1 :(得分:6)

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

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

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

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

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

答案 2 :(得分:1)

以下是每个陈述的不同范围规则。

使用:

  

with语句使命名引用的访问效率低下,因为在运行时之前无法计算此类访问的范围

令:

  

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

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

<强>参考