JavaScript中var与let关键字差异解析及代码异常原因排查
Let's break down the core differences between var and let first, then dive into why you might see discrepancies between your two code snippets.
Core Differences Between var and let
- Scope:
varis function-scoped: it's accessible anywhere within the function it's declared in (even outside loops or conditional blocks inside that function).letis block-scoped: it only exists within the nearest enclosing block (like the{}of aforloop,ifstatement, etc.).
- Hoisting & Temporal Dead Zone (TDZ):
vargets hoisted to the top of its function scope and initialized toundefined—you can reference it before declaration without an error (though the value will beundefined).letis also hoisted, but it doesn't get initialized until its declaration line. Accessing it before declaration throws aReferenceError(this is the TDZ).
- Re-declaration:
- You can re-declare the same
varvariable multiple times in the same scope without issues. - Re-declaring a
letvariable in the same scope throws aSyntaxError.
- You can re-declare the same
- Global Binding:
- When declared in the global scope,
varattaches itself to thewindowobject (in browsers) orglobal(in Node.js). letdeclared globally doesn't attach to these global objects—it stays in a separate global scope.
- When declared in the global scope,
Analyzing Your Code Snippets
Wait a second—if we run both your code snippets as-is, they actually produce the same output ([3, 2, 1])! The var and let versions of your array-reversing function work identically here because we're only using i inside the loop block.
But if you're seeing an error with the let version, it's almost certainly because you're trying to access i outside the for loop block somewhere in your actual code. Let's demonstrate that scenario:
Modified var Version (Works)
function revarr(arr) { for (var i = 0; i < arr.length / 2; i++) { [arr[i], arr[arr.length - 1 - i]] = [arr[arr.length - 1 - i], arr[i]]; } console.log(i); // Outputs 2 (since var is function-scoped) return arr; } console.log(revarr([1, 2, 3])) // [3, 2, 1]
Modified let Version (Throws Error)
function revarr(arr) { for (let i = 0; i < arr.length / 2; i++) { [arr[i], arr[arr.length - 1 - i]] = [arr[arr.length - 1 - i], arr[i]]; } console.log(i); // Throws ReferenceError: i is not defined return arr; } console.log(revarr([1, 2, 3]))
Why This Happens:
- With
var,iis function-scoped, so it exists throughout the entirerevarrfunction—even after the loop finishes. - With
let,iis block-scoped to theforloop's{}block. Once the loop ends,iis no longer accessible, hence theReferenceError.
Another common scenario where var and let behave differently is with asynchronous code inside loops (like setTimeout), but that doesn't apply to your synchronous array-reversing function.
内容的提问来源于stack exchange,提问作者sunny singh

