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)
您可以使用both 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);
}
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声明没有-灵活性较差,有时一个优势.
我能想到的最好的是,它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块的笨拙.