过时
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"
}
答案 0 :(得分:8)
您可以使用with
和let
语句来实现相同的目标,但我在此处看到两个显着差异。最后,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
语句在严格模式下不可用。
<强>参考强>