如果let关键字引入了块范围的正确实现,那么var是否还有一个用例?我从软件设计的角度来看这个,而不是语法,"你能做到"的立场.
Fel*_*ing 15
如果
let关键字引入了块范围的正确实现,那么var是否还有一个用例?
可能有一个用例:let全局范围内的声明不会在全局对象上创建属性.例:
"use strict"; // for chrome
var foo = 42;
let bar = 21;
console.log('window.foo (var)', window.foo); // 42
console.log('window.bar (let)', window.bar); // undefinedRun Code Online (Sandbox Code Playgroud)
全局环境记录的对象Environment Record组件包含所有内置全局变量(第18节)的绑定以及全局代码中包含的FunctionDeclaration,GeneratorDeclaration或VariableStatement引入的所有绑定.全局代码中所有其他ECMAScript声明的绑定包含在全局环境记录的声明性环境记录组件中.
但是,通过直接分配给全局对象来创建显式全局变量,也可以轻松解决这个问题:
window.foo = 42;
Run Code Online (Sandbox Code Playgroud)
这也是创建全局类btw的唯一方法,因为class声明具有相同的行为.
(注意:我不主张使用全局变量)
有一些只能使用的语法结构var,但这更多是规范演变的结果,并没有真正用于任何实际目的.例如:
if (true)
var foo = 42; // valid but kind of useless or bad design
// vs
if (true)
let foo = 42; // invalid
Run Code Online (Sandbox Code Playgroud)
阻止范围不是唯一有用的功能.该时间死区是另一个方便的功能更容易发现漏洞.相比:
var foo = 42;
function bar() {
console.log(foo); // undefined
var foo = 21;
}
bar();
// vs
var foo = 42; // or `let`, doesn't matter
function bar() {
console.log(foo); // ReferenceError, temporal dead zone
let foo = 21;
}
bar();
Run Code Online (Sandbox Code Playgroud)
尝试访问let尚未初始化的变量时,会出现引用错误.
let不能在全球范围内使用还没有。var能够。
这是您let在严格模式之外尝试全局设置时从Chrome中获得的信息:
严格模式之外尚不支持块范围的声明(let,const,函数,类)
实际上,我为自己找到了一些用例。
有时您可能想在 try-catch 中声明变量,如下所示:
try {
//inits/checks code etc
let id = getId(obj);
var result = getResult(id);
} catch (e) {
handleException(e);
}
//use `result`
Run Code Online (Sandbox Code Playgroud)
随着let该result宣言将是之前try,其早期和断章取义的作者和代码的读者是有点。
条件声明也是如此:
if (opts.re) {
var re = new RegExp(opts.re);
var result = match(re);
if (!result) return false;
}
//use result here safely
Run Code Online (Sandbox Code Playgroud)
使用let此代码会有点被迫抱怨“良好的风格”,尽管这可能不切实际。
我也可以想象你想使用属于循环块的变量的情况:
for (var x = 0; x < data.width; x++) {
if (data[x] == null) break;
//some drawing/other code
}
//here we have the `x` pointing to the end of data
Run Code Online (Sandbox Code Playgroud)
美貌标准高的人可能会认为不整洁,我自己更喜欢lets,但是如果我编辑的代码已经包含vars - 使用它们很自然并且使编码更容易。