teoria practicas descargar definicion buenas javascript scope scoping hoisting

practicas - javascript descargar



Alcance y elevaciĆ³n de funciones de Javascript (14)

Acabo de leer un excelente artículo sobre JavaScript Scoping and Hoisting de Ben Cherry en el que da el siguiente ejemplo:

var a = 1; function b() { a = 10; return; function a() {} } b(); alert(a);

Usando el código de arriba, el navegador alertará "1".

Todavía no estoy seguro de por qué devuelve "1". Le vienen a la mente algunas de las cosas que dice: todas las declaraciones de funciones se elevan a la cima. Puede determinar el alcance de una variable usando la función. Todavía no hace clic para mí.


  1. la función de declaración de function a(){} se iza primero y se comporta como var a = function () {}; , por lo tanto, en el ámbito local a se crea.
  2. Si tiene dos variables con el mismo nombre (una en global y otra en local), la variable local siempre tiene precedencia sobre la variable global.
  3. Cuando establece a=10 , está configurando la variable local a , no la global.

Por lo tanto, el valor de la variable global sigue siendo el mismo y se obtiene, alertado 1


¿Cuál es la manzana de la discordia en este pequeño fragmento de código?

Caso 1:

Incluya la function a(){} definición dentro del cuerpo de la function b siguiente manera. logs value of a = 1

var a = 1; function b() { a = 10; return; function a() {} } b(); console.log(a); // logs a = 1

Caso 2

Excluya la function a(){} definición dentro del cuerpo de la function b siguiente manera. logs value of a = 10

var a = 1; function b() { a = 10; // overwrites the value of global ''var a'' return; } b(); console.log(a); // logs a = 10

La observación lo ayudará a darse cuenta de que la sentencia console.log(a) registra los siguientes valores.

Caso 1: a = 1

Caso 2: a = 10

Poses

  1. var a se ha definido y declarado léxicamente en el ámbito global.
  2. a=10 Esta declaración está reasignando el valor a 10, se encuentra léxicamente dentro de la función b.

Explicación de ambos casos

Debido a la function definition with name property de la function definition with name property a es igual a la variable a . La variable a dentro del function body b la function body b convierte en una variable local. La línea anterior implica que el valor global de a permanece intacto y el valor local de a se actualiza a 10.

Entonces, lo que pretendemos decir es que el código a continuación

var a = 1; function b() { a = 10; return; function a() {} } b(); console.log(a); // logs a = 1

Es interpretado por el intérprete JS de la siguiente manera.

var a = 1; function b() { function a() {} a = 10; return; } b(); console.log(a); // logs a = 1

Sin embargo, cuando eliminamos la function a(){} definition , el value of ''a'' declarado y definido fuera de la función b, ese valor se sobrescribe y cambia a 10 en el caso 2. El valor se sobrescribe porque a=10 refiere a la declaración global y si fuera declarada localmente debemos escribir var a = 10; .

var a = 1; function b() { var a = 10; // here var a is declared and defined locally because it uses a var keyword. return; } b(); console.log(a); // logs a = 1

Podemos aclarar aún más nuestra duda al cambiar la name property del name property en la function a(){} definition por algún otro nombre que ''a'' sea ''a''

var a = 1; function b() { a = 10; // here var a is declared and defined locally because it uses a var keyword. return; function foo() {} } b(); console.log(a); // logs a = 1


Alzando en JavaScript significa que las declaraciones de variables se ejecutan a través del programa antes de que se ejecute cualquier código. Por lo tanto, declarar una variable en cualquier parte del código es equivalente a declararla al principio.


Aquí está mi resumen de la respuesta con más anotaciones y un violín que lo acompaña.

// hoisting_example.js // top of scope ie. global var a = 1 var a = 1; // new scope due to js'' functional (not block) level scope function b() { a = 10; // if the function ''a'' didn''t exist in this scope, global a = 10 return; // the return illustrates that function ''a'' is hoisted to top function a(){}; // ''a'' will be hoisted to top as var a = function(){}; } // exec ''b'' and you would expect to see a = 10 in subsequent alert // but the interpreter acutally ''hoisted'' the function ''a'' within ''b'' // and in doing so, created a new named variable ''a'' // which is a function within b''s scope b(); // a will alert 1, see comment above alert(a);

https://jsfiddle.net/adjavaherian/fffpxjx7/


El izado de funciones significa que las funciones se mueven a la parte superior de su alcance. Es decir,

function b() { a = 10; return; function a() {} }

será reescrito por el interpetador a este

function b() { function a() {} a = 10; return; }

Extraño, ¿eh?

Además, en este caso,

function a() {}

se comportó igual que

var a = function () {};

Entonces, en esencia, esto es lo que hace el código:

var a = 1; //defines "a" in global scope function b() { var a = function () {}; //defines "a" in local scope a = 10; //overwrites local variable "a" return; } b(); alert(a); //alerts global variable "a"


El izamiento es un concepto de comportamiento de JavaScript. El izado (es decir, el movimiento) es un concepto que explica cómo y dónde deben declararse las variables.

En JavaScript, una variable puede declararse después de que se haya utilizado porque el intérprete de JavaScript siempre mueve ("eleva") las declaraciones de funciones y las declaraciones de variables de manera invisible a la parte superior de su ámbito de contenido.

Encontramos dos tipos de elevación en la mayoría de los casos.

1. Levantamiento de declaración variable

Vamos a entender esto por esta pieza de código.

a = 5; // Assign 5 to a elem = document.getElementById("demo"); // Find an element elem.innerHTML = a; // Display a in the element var a; // Declare a //output-> 5

Aquí la declaración de la variable a será alojada de manera invisible por el intérprete de JavaScript en el momento de la compilación. Así que pudimos obtener el valor de a. Pero este enfoque de declaración de variables no se recomienda ya que deberíamos declarar las variables arriba ya como esta.

var a = 5; // Assign and declare 5 to a elem = document.getElementById("demo"); // Find an element elem.innerHTML = a; // Display a in the element // output -> 5

considera otro ejemplo.

function foo() { console.log(x) var x = 1; }

en realidad se interpreta de esta manera:

function foo() { var x; console.log(x) x = 1; }

En este caso, x será indefinido

No importa si se ejecutó el código que contiene la declaración de la variable. Considera este ejemplo.

function foo() { if (false) { var a = 1; } return; var b = 1; }

Esta función resulta ser así.

function foo() { var a, b; if (false) { a = 1; } return; b = 1; }

En la declaración de variables, solo los polipastos de definición de variables, no la asignación.

  1. Elevación de declaración de función

A diferencia de la elevación variable, también se izará el cuerpo de la función o el valor asignado. Considera este código

function demo() { foo(); // this will give error because it is variable hoisting bar(); // "this will run!" as it is function hoisting var foo = function () { alert("this would not run!!"); } function bar() { alert("this will run!!"); } } demo();

Ahora, como hemos entendido tanto el cambio de función como el de función, comprendamos este código ahora.

var a = 1; function b() { a = 10; return; function a() {} } b(); alert(a);

Este código resultará ser así.

var a = 1; //defines "a" in global scope function b() { var a = function () {}; //defines "a" in local scope a = 10; //overwrites local variable "a" return; } b(); alert(a);

La función a () tendrá alcance local dentro de b (). a () se moverá a la parte superior mientras interpreta el código con su definición (solo en caso de elevación de función), por lo que ahora tendrá alcance local y por lo tanto no afectará el alcance global de un tiempo que tenga su propio alcance dentro de la función b () .


El izamiento es un concepto hecho para que lo hagamos más fácil de entender. Lo que realmente sucede es que las declaraciones se hacen primero con respecto a sus ámbitos y las asignaciones se realizarán después de eso (no al mismo tiempo).

Cuando ocurren las declaraciones, var a , luego function b y dentro de ese alcance b , se declara la function a .

Esta función a sombreará la variable a proveniente del alcance global.

Después de que las declaraciones hayan finalizado, los valores asignados comenzarán, el global a obtendrá el valor 1 y a la function b interior function b obtendrá 10 . cuando alert(a) , llamará a la variable de alcance global real. Este pequeño cambio en el código lo hará más claro

var a = 1; function b() { a = 10; return a; function a() { } } alert(b()); alert(a);


Está sucediendo porque el nombre de la variable es el mismo que el nombre de la función que significa "a". Por lo tanto, debido a la elevación de Javascript, intenta resolver el conflicto de nombres y devolverá a = 1.

También estaba confundido acerca de esto hasta que leí esta publicación en "JavaScript Hoisting" http://www.ufthelp.com/2014/11/JavaScript-Hoisting.html

Espero eso ayude.


La función a se iza dentro de la función b :

var a = 1; function b() { function a() {} a = 10; return; } b(); alert(a);

que es casi como usar var :

var a = 1; function b() { var a = function () {}; a = 10; return; } b(); alert(a);

La función se declara localmente y la configuración solo ocurre en el ámbito local, no en la var global.


Lo que debes recordar es que analiza la función completa y resuelve todas las declaraciones de variables antes de ejecutarla. Asi que....

function a() {}

realmente se convierte

var a = function () {}

var a fuerza a un ámbito local, y el alcance variable es a través de toda la función, por lo que la variable global a es todavía 1 porque ha declarado a en un ámbito local convirtiéndola en una función.


Long Post!

¡Pero limpiará el aire!

La forma en que funciona Java Script es que implica un proceso de dos pasos:

  1. Compilación (por así decirlo): este paso registra variables y declaraciones de funciones y sus respectivos ámbitos. No implica evaluar la expresión de la función: var a = function(){} o expresión variable (como asignar 3 a x en el caso de var x =3; que no es más que la evaluación de la parte RHS).

  2. Intérprete: esta es la parte de ejecución / evaluación.

Verifique el resultado del siguiente código para comprender:

//b() can be called here! //c() cannot be called. console.log("a is " + a); console.log("b is " + b); console.log("c is " + c); var a = 1; console.log("Now, a is " + a); var c = function() {}; console.log("Now c is " + c); function b() { //cannot write the below line: //console.log(e); //since e is not declared. e = 10; //Java script interpreter after traversing from this function scope chain to global scope, is unable to find this variable and eventually initialises it with value 10 in global scope. console.log("e is " + e) // works! console.log("f is " + f); var f = 7; console.log("Now f is " + f); console.log("d is " + d); return; function d() {} } b(); console.log(a);

Vamos a romperlo:

  1. En la fase de compilación, ''a'' se registraría en el alcance global con el valor '' undefined ''. Lo mismo ocurre con '' c '', su valor en este momento sería '' undefined '' y no la '' function() ''. '' b '' se registraría como una función en el alcance global. Dentro del alcance de b , '' f '' se registraría como una variable que no estaría definida en este momento y se registraría la función '' d ''.

  2. Cuando se ejecuta el intérprete, se puede acceder a las variables declaradas y a la function() (y no a las expresiones) antes de que el intérprete llegue a la línea de expresión real. Entonces, las variables se imprimirían '' undefined '' y la función anónima declarada se puede llamar antes. Sin embargo, intentar acceder a la variable no declarada antes de la inicialización de su expresión daría lugar a un error como:

console.log(e) e = 3;

Ahora, qué sucede cuando tienes declaración de variables y funciones con el mismo nombre.

La respuesta es : las funciones siempre se izan antes y si se declara la misma variable de nombre, se trata como duplicado e ignorado. Recuerde, el orden no importa. Las funciones siempre tienen prioridad. Pero durante la fase de evaluación puede cambiar la referencia de la variable a cualquier cosa (Almacena lo que fue la última tarea) Eche un vistazo al siguiente código:

var a = 1; console.log("a is " + a); function b() { console.log("a inside the function b is " + a); //interpreter finds ''a'' as function() in current scope. No need to go outside the scope to find ''a''. a = 3; //a changed console.log("Now a is " + a); return; function a() {} } var a; //treated as duplicate and ignored. b(); console.log("a is still " + a + " in global scope"); //This is global scope a.


Todo depende del alcance de la variable ''a''. Permítanme explicar creando ámbitos como imágenes.

Aquí JavaScript creará 3 ámbitos.

i) Alcance global. ii) Alcance de la función b (). iii) Función a () ámbito.

Está claro cuando llamas al alcance del método de ''alerta'' que pertenece a Global ese momento, por lo que elegirá el valor de la variable ''a'' del alcance Global solo que es 1.


function a() { } es una declaración de función, que crea a variable local para la función b .
Las variables se crean cuando se analiza una función, independientemente de si se ejecuta la sentencia var o function.

a = 10 establece esta variable local.


Scrappe & closure & hoisting (var / function)

  1. scpope: la var global se puede acceder en cualquier lugar (todo el alcance del archivo), var local solo se puede acceder por el alcance local (función / bloque de alcance)!
    Nota: si una variable local no utiliza palabras clave var en una función, ¡se convertirá en una variable global!
  2. cierre: una función interna de la otra función, que puede acceder al alcance local (función principal) y al alcance global, mientras que otros no pueden acceder a los vars. a menos que lo devuelva como valor de retorno
  3. elevación: mueva todos los valores / funciones de declarar / declarar no declarado a la parte superior del alcance, luego de asignar el valor o nulo!
    Nota: ¡solo mueva el declare, no mueva el valor!

var a = 1; //"a" is global scope function b() { var a = function () {}; //"a" is local scope var x = 12; //"x" is local scope a = 10; //global variable "a" was overwrited by the local variable "a" console.log("local a =" + a); return console.log("local x = " + x); } b(); // local a =10 // local x = 12 console.log("global a = " + a); // global a = 1 console.log("can''t access local x = /n"); // can''t access local x = console.log(x); // ReferenceError: x is not defined