Trace the binding before the value
The output is undefined, 20, then 10. When show begins, JavaScript has already created a local value binding for the function because var declarations are function-scoped and hoisted. That local binding shadows the global value throughout the entire function body, including the lines above the written declaration.
Only the declaration is processed early; the assignment value = 20 remains where it appears. The local binding therefore contains undefined at the first console.log. After the assignment runs, the second log reads 20 from the same local binding. Returning from show removes that function activation. Nothing in the function assigned to the global binding, so the final log outside the function still reads the global 10. This is shadowing, not a temporary read of the global followed by its replacement.