使用 let/block 范围界定的实际优势是什么?

What is the actual advantage of using let/block scoping?

我似乎看不出使用 let 的实际优势。当然,如果我有一个 for 循环,我会使用 let i = 0 而不是 var i = 0 并且 i 现在属于 for 循环块的范围。但这真的有利吗?我的意思是我可以使用 var 并让变量具有函数范围访问权限,但只是不在我不需要的地方使用它?阻止范围界定有什么好处?

我了解 var 和 let 之间的区别,我想更连贯地了解 let 的特殊优势。

您已经提到了一个优点:循环中的块作用域。这避免了 defining functions inside a loop 的问题,我认为这是 JavaScript 新手最大的陷阱之一:

// With var
var elements = document.querySelectorAll('.var');
for (var i = 0; i < elements.length; i++) {
  elements[i].onclick = function() {
    console.log("I'm element #" + (i + 1) + ".");
  };
}

// With let
elements = document.querySelectorAll('.let');
for (let i = 0; i < elements.length; i++) {
  elements[i].onclick = function() {
    console.log("I'm element #" + (i + 1) + ".");
  };
}
<h3>With <code>var</code></h3>
<div class="var">Click me!</div>
<div class="var">Click me!</div>

<h3>With <code>let</code></h3>
<div class="let">Click me!</div>
<div class="let">Click me!</div>

另一个优点是 let 变量默认不初始化。这使得在更高范围内尝试访问具有相同名称的变量时更容易发现错误:

// With `var`, we get `undefined` which can be tricky to debug in more
// complex code.
var foo = 42;

function bar() {
  console.log(foo); // undefined
  var foo = 21;
}
bar();

// With `let`, we get a ReferenceError, which makes it clear that we made
// a mistake here.
var foo = 42;

function bar() {
  console.log(foo); // ReferenceError
  let foo = 21;
}
bar();


总而言之,这使 JavaScript 更符合其他语言的工作方式。