为何var x = x = x || {}比var x = x || {}的写法更严谨?
var x = x = x || {} is considered more rigorous than var x = x || {} Great question! The difference boils down to how JavaScript handles variable hoisting and assignment chaining, and while the two lines behave similarly in most cases, the chained assignment addresses subtle edge cases related to scoping and duplicate declarations.
Let’s break it down step by step:
1. How var x = x || {} works
Thanks to variable hoisting, JavaScript moves all var declarations to the top of their containing scope before executing any code. So this line is equivalent to:
var x; // Declaration is hoisted to the top x = x || {}; // Assignment happens in place
- If
xwas already declared in the current scope (even if it’sundefined), the right-hand sidexrefers to this local, undefined variable. The result isxgets set to{}. - If you intended to reuse an
xfrom an outer (e.g., global) scope, this line will accidentally create a localxinstead—because the hoistedvar xdeclares a local variable, overriding the outer one in the scope chain.
2. How var x = x = x || {} works
Again, variable hoisting first moves the var x declaration to the top. The chained assignment uses JavaScript’s right-associative assignment operator, so it’s equivalent to:
var x; // Hoisted declaration x = (x = (x || {})); // Right-to-left assignment
The key value here lies in defensive coding and explicit intent:
- When you have duplicate
vardeclarations in the same scope (e.g.,var x;followed later byvar x = x = x || {}), the chained assignment makes it explicit that you’re intentionally reusing the existingx(whether defined or not) and reassigning it in a single, clear step. - In older JavaScript environments with less consistent scoping behavior, this pattern reduces the risk of accidentally creating implicit global variables (though
varalready mitigates this) and leaves less room for the engine or other developers to misinterpret your intent.
3. Practical note
In modern JavaScript, var x = x || {} is still a widely accepted best practice for initializing namespace objects—it’s concise and works for most cases. The chained version is more of a defensive coding pattern that addresses rare edge cases and makes your intent more explicit, which is why some sources consider it more rigorous.
内容的提问来源于stack exchange,提问作者Jacques Gaudin

