Answer to
@ jmar777 is by far the best explanation and breakdown of the spec. Nevertheless, I find that for us practical students a little illustrative code is useful !;)
main idea
- "Declaration" makes the variable available to the entire area.
- 'Assignment' gives the variable a specific value at this point in the code. If you try to assign a value to a variable that has never been declared in this region or the parent region, the variable is implicitly declared in the global region (equal to the type
window.varName = value ). - “Initialization” is what happens “backstage” or “under the hood,” so to speak. At run time, all declared variables are initialized with the initial assignment
undefined (even if they immediately get the assigned other value in the first line of code).
Thus, initialization is not a term that matters to us. We declare and assign, and the Javascript engine is initialized.
So, to directly answer the example in your question:
var example; declares a variable that is set to undefined upon initialization.var example = "hi" declares a variable that first gets an undefined value, but when this line of code is actually reached at runtime, it gets an overridden hello string.
Illustrative code
function testVariableDeclaration() { // This behaves 'as expected'.... console.log(test2, 'no value assigned yet'); // --> undefined 'no value assigned yet' // ....but shouldn't our actual expectation instead be that it'll throw an error since // it doesn't exist yet? See the final console.log() below! // As we all know.... test1 = 'global var'; // ....a variable assignment WITHOUT declaration in the current // scope creates a global. (It IMPLICITLY declared.) // But a little counter-intuitively.... test2 = 'not global'; // Although this variable also appears to be assigned without // declaration like 'test1', the declaration for 'test2' that // appears *later* in the code gets hoisted so that it already // been declared in-scope prior to this assignment. console.log( test1, window.test1 === test1 ); // --> 'global var' TRUE console.log( test2, window.test2 === test2 ); // --> 'not global' FALSE var test2; // As shown by the above console.log() outputs, this variable is scoped. console.log( test3 ); // Throws a ReferenceError since 'test3' is not declared // anywhere, as opposed to the first console.log() for 'test2'. }
Scale effects on declaration / assignment
The difference between a declaration and an assignment is different, then a variable declaration always creates a new variable in the current scope ( myVar scopeB ), even if a variable with the same name already exists in the parent scope ( myVar scopeA ). Then we can assign a new value to myVar scopeB at any point in the current scope without re-declaring. (This assignment does not affect the value of myVar scopeA .) Upon reaching the end of scopeB , myVar scopeB will no longer be available for assignment.
On the other hand, if we assign a value to a variable in a given area without declaring it in that area, it will be assigned to the next-high-up declaration in the "scope chain" (or global will be declared implicitly if a higher declaration is not found).
Thus, a variable should only be declared once for each area, with each declaration overriding any declarations made in the parent areas (i.e., creating a separate variable). But it must be declared in the area, if it must be unique to this area. Assignment can occur as many times as required, but affects only the most “strongly declared” variable (due to the lack of a better term).