Si abres la consola del navegador, con la combinación de teclas Ctrl + Shift + I o clic derecho e "Inspeccionar" en tu navegador preferido (de preferencia Google Chrome).
Ejecuta la palabra window, se desplegará un objeto en el que se encuentran todas las funcionalidades de JavaScript, por ejemplo ejecuta window.console.log("Hola") tendrá el mismo comportamiento que console.log("Hola").
Si ejecutas this observarás que muestra el mismo objeto que window, esto es porque en un contexto global, estos dos objetos son iguales. Pero en otros contextos, como el de una función o una clase, this cambia.
Qué es hoisting
Hoisting es un término para describir que las declaraciones de variables y funciones son movidas a la parte superior del scope más cercano: scope global o de función. Esto sucede solamente con las declaraciones y no con las asignaciones.
El código permanece igual, solo es una interpretación del motor de JavaScript que intenta ayudar a optimizar el código, pero en este caso provoca errores y resultados no esperados. En el caso de las variables solo sucede cuando son declaradas con var.
Hoisting en variables declaradas con var
En el siguiente código, la respuesta del console.log es undefined, porque al hacer referencia a una variable que no está declarada, el motor de JavaScript crea esta variable antes de la declaración y le asigna un valor de undefined.
console.log(nombre)// undefinedvar nombre ="Andres"
var nombre =undefinedconsole.log(nombre)nombre ="Andres"
Lo adecuado es evitar utilizar var para declarar las variables con let o const, ya que estas últimas el proceso de optimización que realiza el motor de JavaScript no generará variables con el valor de undefined antes de su declaración.
Una preguntica de examen
Una estricta definición de hoisting sugiere que las declaraciones de variables y funciones son físicamente movidas al comienzo del código,asignandolas en memoria dentro de un contexto de ejecucion.
Lo tendré muy en cuenta, todavía no llego hasta allá
Muchas gracias
Lo que escribes:
console.log(nombre);apellido();var nombre ="Diego";functionapellido(){console.log("De Grada");}
Como el motor de JavaScript lo interpreta:
var nombre =undefined;functionapellido(){console.log("De Grada");}console.log(nombre);apellido();nombre ="Diego";
Si te preguntas cuál pone más arriba, ¿Las variables o las funciones?
La respuesta es las variables. Probemos esto:
var nombre;functionnombre(){}typeof nombre;// Output: "function"
¿Y si ponemos primero la función y luego la variable?
Pero, si declaras una variable y le asignas un valor en la misma linea el resultado es diferente:
var nombre ="Platzi";functionnombre(){}typeof nombre;// Output: "string"
Esto es porque JavaScript hace hoisting solo de la declaración de la variable. JavaScript trata la declaración y asignación en una sola linea como dos pasos, por lo que si escribimos:
var nombre ="Platzi";
El motor lo interpreta así:
var nombre =undefined;nombre ="Plazi";
Así que cuando escribimos:
var nombre ="Platzi";functionnombre(){}typeof nombre;// Output: "string"
Como lo interpreta el motor de JavaScript es así:
var nombre =undefined;functionnombre(){}nombre ="Platzi";typeof nombre;// Output: "string"
Es decir que "se deja atrás" la asignación.
Obviamente ningún desarrollador debería de escribir código así de confuso, esto es solo para saber como funciona JavaScript y su engine, ese conocimiento te hace un mejor desarrollador y te destaca de entre otros.
Me encanto la explicación, de una recorde todo :)
Este aporte esta súper completo en todos los sentidos.
Hoisting
Si llamamos una variable antes de ser declarada, el compiler crea la variable en la memory heap y la inicializa como undefined
En el caso de las funciones es distinto, primero mandamos a llamar a las funciones antes de ejecutarlas.
El hoisting a veces funciona pero no tenemos control de las variables que se van a cambiar
Si llamamos a una constante (const) antes de inicializar retorna un error de tipo: Uncaught ReferenceError, que corresponde a variables que son referenciadas pero no pudieron ser capturadas
En estas clases se explica también cómo funciona el Hoisting a nivel de lenguaje: Hoisting, ¿Qué es el Hoisting? :D
#Gracias
Cuando el motor JS obtiene nuestro script, lo primero que hace es configurar la memoria para los datos de nuestro código. No se ejecuta ningún código en este punto, simplemente está preparando todo para su ejecución. La forma en que se almacenan las declaraciones de función y las variables es diferente.
.
Las funciones se almacenan con una referencia a la función completa:
.
Con las variables es un poco diferente. ES6 introdujo dos nuevas palabras clave para declarar variables: let y const. Las variables declaradas con la palabra clave let o const se almacenan sin inicializar:
.
Las variables declaradas con la palabra clave var se almacenan con el valor predeterminado de undefined:
.
Ahora que ha terminado la fase de creación, podemos ejecutar el código. Veamos qué sucede si tuviéramos 3 sentencias console.log encima del archivo, antes de declarar la función o cualquiera de las variables.
Dado que las funciones se almacenan con una referencia a todo el código de la función, podemos invocarlas incluso antes de la línea en la que las creamos:
.
Cuando hacemos referencia a una variable declarada con la palabra clave var antes de su declaración, simplemente devolverá su valor predeterminado con el que se almacenó "undefined". Sin embargo, esto a veces puede provocar un comportamiento "inesperado". En la mayoría de los casos, esto significa que le estás haciendo referencia sin querer (probablemente no quieras que tenga el valor de undefined):
.
Para evitar poder hacer referencia accidentalmente a una variable undefined, como podríamos hacer con la palabra clave var, se lanzará un ReferenceError cada vez que intentamos acceder a variables no inicializadas.
La "zona" antes de su declaración real se denomina "zona muerta temporal". No puede hacer referencia a las variables (¡esto también incluye las clases ES6!) antes de su inicialización:
.
Cuando el motor pasa la línea en la que realmente declaramos las variables, los valores en la memoria se sobrescriben con los valores con los que realmente los declaramos (hay un pequeño error en la animación, debiera ser la número 7 y no la 6):
.
++Resumen rápido:++
– Las funciones y variables se almacenan en la memoria para un contexto de ejecución antes de ejecutar nuestro código. A esto se le llama Hoisting .
– Las funciones se almacenan con una referencia a la función completa, las variables con la palabra clave var con el valor de undefined y las variables con la palabra clave let y const se almacenan sin inicializar.
Muy claro y completo, Excelente aporte!
Gracias por el aporte, me quedo mucho mas claro el hoisting!
Cuando comparamos window con this y da true, ese true NO lo da porque sean objetos iguales y tengan la información, ese true lo da porque ambas variables son EL MISMO objeto, es decir, ambas variables tienen la misma referencia de memoria, ambas variables están apuntando a la misma referencia en memoria de la computadora, por lo que, si cambias algo en una, también se cambiará en otra ^^
https://developer.mozilla.org/es/docs/Glossary/Hoisting
.
Hoisting es un término que no encontrará utilizado en ninguna especificación previa a ECMAScript® 2015 Language Specification. El concepto de Hoisting fue pensado como una manera general de referirse a cómo funcionan los contextos de ejecución en JavaScript (específicamente las fases de creación y ejecución). Sin embargo, el concepto puede ser un poco confuso al principio.
.
Conceptualmente, por ejemplo, una estricta definición de hoisting sugiere que las declaraciones de variables y funciones son físicamente movidas al comienzo del código, pero esto no es lo que ocurre en realidad. Lo que sucede es que las declaraciones de variables y funciones son asignadas en memoria durante la fase de compilación, pero quedan exactamente en dónde las has escrito en el código.
let y const importantes para evitar el hoisting !
por?
Estimado Alex, por lo que hizo el prof en clase, que con ellos aunque te equivoques en llamar a una variable antes de ser declarada, el hoisting ya no se aplique en ellas y así se evita problemas en el proceso de lo que quieres hacer con tu código de JavaScript
Como buena práctica está bien evitar el hoisting. Primero declarar las funciones y variables, antes de usarlas.
Zona muerta temporal
Es el lugar donde se guardan las variables declaradas con let y const, cuya función es impedir el acceso a ellas antes de ser inicializadas. Por eso es mejor usar let y const por sobre var
A manera de resumen para evitar el hoisting es necesario:
Declarar variables y/o funciones
Inicializar variables y/o funciones (en caso de ser arrow functions)
Llamar o usar variables y/o funciones
El Hoisting no aplica a let y const.
Por eso es recomendado no usar var.
Tampoco a la funciones expresivas:
const myFunc = function() {}
Puntual y claro. Gracias por esto!
El hoisting es un poseso de compilador de JS que consiste en que la declaración de las variables y las funciones son llevadas a l inicio del código sin importas sus propiedades, para su procesamiento sin embargo, la inicialización de las variables no es llevada al inicio del código para su compilación, si no solo su declaración, lo suele dar espacios a errores cuando se declara una variable sin inicializarla y se procesa en el código antes de haber llegado a sus inicialización lo cual nos suele dar una variable con calor undefined, ya que la variables si fue almacenada en la memoria, pero no se asigno un valor asta después de la ejecución ejemplo :
saludo()functionsaludo(){console.log("Hola"+ nombre)}var nombre ="Miguel"
El resultado sera
Holaundefined
En base a este ejemplo fue porque se cometió el error de usar la variable antes de inicializar pues sin problema el compilador le asigna memoria pero no el valor asta después.
Le asigna memoria a la variable y le da valor de undefined a suceder la asignación de memoria.
var nombre =undefined;functionsaludo(){console.log("Hola"+ nombre);}saludo()
Aqui como hemos visto que la variable como undefined y posterior mente se utiliza al llegar a l alinea del saludo()
Pero si declaro si hago este siguiente codigo me va a regresar el nombre que le puse a la variable, le puse comillas para separar el hola y el nombre
var nombre =undefined;functionsaludo(){console.log("Hola"+" "+ nombre);}var nombre ="Miguel";saludo()
el resultado seria Hola Miguel
La forma de hacer que corrercta de hacerlo es esta
var nombre ="Miguel";functionsaludo(){console.log("Hola"+" "+ nombre)}saludo()
espero que le ayude esto
¿El hoisting es exclusivo de JavaScript, existe algun otro lenguaje de programacion que aplique hoisting?
En Python sucede algo similar al hoisting de JavaScript. Desconozco si hay algún otro lenguaje donde se aplique hoisting.
El hoisting aparece tambien en VBScript - Rhinoscript, GO y Ruby
Siempre es buena idea recurrir al video que, desde mi punto de vista, explica de mejor forma lo que es el hoisting.
Hola Armando
Y los videos de Sacha son muy buenos.
Saludos
Comparto los apuntes que he hecho, espero les sea de ayuda para entender estos temas.
Parser => Significa analizar y convertir un programa a un formato interno que un entorno de ejecución pueda ejecutar, por ejemplo, el motor JavaScript dentro de los navegadores.