Detalles teóricos
JavaScript tiene dos ámbitos: global y local. Una variable que se declara fuera de la definición de una función es una variable global y su valor es accesible y modificable desde su programa. Si se declara dentro de la definición de una función, será local. Se crea y se destruye cada vez que se ejecuta la función y ningún código externo a la función puede tener acceso a ella. JavaScript no admite el ámbito de bloque (en el que un conjunto de llaves {. . .} define un nuevo ámbito), excepto en el caso especial de variables de ámbito del bloque.
Una variable local puede tener el mismo nombre que una variable global, pero es totalmente independiente; el cambio del valor de una variable no tiene efecto en la otra. Solo la versión local tiene significado dentro de la función en que se declara.
JavaScript procesa todas las declaraciones de variables antes de ejecutar cualquier código, con independencia de que la declaración se encuentre o no dentro de un bloque condicional o de otra construcción. Una vez que JavaScript encuentra todas las variables, ejecuta el código en la función. Si una variable se declara implícitamente dentro de una función (es decir, si aparece en el lado izquierdo de una expresión de asignación pero no se ha declarado con var), se crea como variable global.
Variables de ámbito del bloque
A día de hoy exite compatibilidad con prácticamente todos los navegadores para let y const, que son variables de ámbito del bloque. Para estas variables, las llaves {. . .} definen un ámbito nuevo. Cuando establezca una de estas variables en un valor específico, el valor solo se aplicará al ámbito en el que se establece.