variable valor usar una scripts pasar paginas otra globales funciones funcion entre cambiar ambito javascript function variables scope var

valor - ¿Cuál es el alcance de las variables en JavaScript?



variables globales javascript entre paginas (26)

JavaScript de la vieja escuela

Tradicionalmente, JavaScript realmente solo tiene dos tipos de alcance:

  1. Ámbito global : las variables son conocidas en toda la aplicación, desde el inicio de la aplicación (*)
  2. Ámbito funcional : las variables se conocen dentro de la función en la que se declaran, desde el inicio de la función (*)

No voy a explicar esto, ya que ya hay muchas otras respuestas que explican la diferencia.

JavaScript moderno

Las especificaciones de JavaScript más recientes ahora también permiten un tercer ámbito:

  1. Ámbito del bloque : las variables se conocen dentro del bloque en el que se declaran, desde el momento en que se declaran en adelante (**)

¿Cómo creo variables de ámbito de bloque?

Tradicionalmente, creas tus variables así:

var myVariable = "Some text";

Las variables de ámbito de bloque se crean así:

let myVariable = "Some text";

Entonces, ¿cuál es la diferencia entre el alcance funcional y el alcance del bloque?

Para comprender la diferencia entre el alcance funcional y el alcance del bloque, considere el siguiente código:

// i IS NOT known here // j IS NOT known here // k IS known here, but undefined // l IS NOT known here function loop(arr) { // i IS known here, but undefined // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here for( var i = 0; i < arr.length; i++ ) { // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here }; // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here for( let j = 0; j < arr.length; j++ ) { // i IS known here, and has a value // j IS known here, and has a value // k IS known here, but has a value only the second time loop is called // l IS NOT known here }; // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here } loop([1,2,3,4]); for( var k = 0; k < arr.length; k++ ) { // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS NOT known here }; for( let l = 0; l < arr.length; l++ ) { // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS known here, and has a value }; loop([1,2,3,4]); // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS NOT known here

Aquí, podemos ver que nuestra variable j solo se conoce en el primer bucle for, pero no antes y después. Sin embargo, nuestra variable i es conocida en toda la función.

Además, tenga en cuenta que las variables de ámbito de bloque no se conocen antes de declararse porque no están elevadas. Tampoco está permitido volver a declarar la misma variable de ámbito de bloque dentro del mismo bloque. Esto hace que las variables de ámbito de bloque sean menos propensas a errores que las variables de alcance global o funcional, que se elevan y no producen errores en el caso de declaraciones múltiples.

¿Es seguro usar variables de alcance de bloque hoy?

Si es seguro o no usarlo hoy, depende de su entorno:

  • Si está escribiendo el código de JavaScript del lado del servidor ( Node.js ), puede usar la instrucción let forma segura.

  • Si está escribiendo un código de JavaScript del lado del cliente y usa un transpiler (como Traceur ), puede usar de manera segura la declaración let , sin embargo, es probable que su código sea todo menos óptimo con respecto al rendimiento.

  • Si está escribiendo el código JavaScript del lado del cliente y no utiliza un transpiler, debe considerar la compatibilidad con el navegador.

    Hoy, 23 de febrero de 2016, estos son algunos de los navegadores que no admiten o solo tienen soporte parcial:

    • Internet Explorer 10 y anteriores (sin soporte)
    • Firefox 43 y anteriores (sin soporte)
    • Safari 9 e inferior (sin soporte)
    • Opera Mini 8 e inferior (sin soporte)
    • Navegador de Android 4 y anteriores (sin soporte)
    • Opera 36 e inferior (soporte parcial)
    • Chome 51 e inferior (soporte parcial)

Cómo realizar un seguimiento de la compatibilidad del navegador

Para obtener una descripción actualizada de qué navegadores son compatibles con la declaración de let en el momento de leer esta respuesta, consulte esta página Can I Use ?

(*) Las variables de alcance global y funcional pueden inicializarse y usarse antes de declararse porque las variables de JavaScript están hoisted . Esto significa que las declaraciones están siempre en la parte superior del alcance.

(**) Las variables de ámbito de bloque no son elevadas.

¿Cuál es el alcance de las variables en javascript? ¿Tienen el mismo alcance en el interior en lugar de fuera de una función? ó acaso importa? Además, ¿dónde se almacenan las variables si se definen globalmente?


Js modernos, ES6 +, '' const '' y '' let ''

Debería usar el ámbito de bloque para cada variable que cree, al igual que la mayoría de los otros idiomas principales. var está obsoleto Esto hace que su código sea más seguro y más fácil de mantener.

const debe utilizarse para el 95% de los casos . Lo hace así que la referencia variable no puede cambiar. Las propiedades de la matriz, el objeto y el nodo DOM pueden cambiar y probablemente deberían ser const .

let debe ser utilizado para cualquier variable que espera ser reasignada. Esto incluye dentro de un bucle for. Si alguna vez cambia el valor más allá de la inicialización, use let .

El ámbito de bloque significa que la variable solo estará disponible dentro de los paréntesis en los que se declara. Esto se extiende a los ámbitos internos, incluidas las funciones anónimas creadas dentro de su ámbito.


Alcance global :

Las variables globales son exactamente como las estrellas globales (Jackie Chan, Nelson Mandela). Puede acceder a ellos (obtener o establecer el valor), desde cualquier parte de su aplicación. Las funciones globales son como eventos globales (año nuevo, navidad). Puede ejecutarlos (llamarlos) desde cualquier parte de su aplicación.

//global variable var a = 2; //global function function b(){ console.log(a); //access global variable }

Ámbito local:

Si estás en los EE. UU., Puedes conocer a Kim Kardashian, celebridad infame (de alguna manera se las arregla para hacer los tabloides). Pero las personas fuera de los Estados Unidos no la reconocerán. Ella es una estrella local, vinculada a su territorio.

Las variables locales son como las estrellas locales. Solo puede acceder a ellos (obtener o establecer el valor) dentro del alcance. Una función local es como eventos locales: solo puede ejecutar (celebrar) dentro de ese ámbito. Si desea acceder a ellos desde fuera del ámbito, obtendrá un error de referencia

function b(){ var d = 21; //local variable console.log(d); function dog(){ console.log(a); } dog(); //execute local function } console.log(d); //ReferenceError: dddddd is not defined

Consulte este artículo para conocer a fondo el alcance.


ES5 y antes:

Las variables en Javascript inicialmente tenían un ES6alcance de función (pre ) léxica. El término de ámbito léxico significa que puede ver el alcance de las variables "mirando" el código.

Todas las variables declaradas con la varpalabra clave están sujetas a la función. Sin embargo, si se declaran otras funciones dentro de esa función, esas funciones tendrán acceso a las variables de las funciones externas. Esto se llama una cadena de alcance . Funciona de la siguiente manera:

  1. Cuando una función busca resolver un valor variable, primero mira su propio ámbito. Este es el cuerpo de la función, es decir, todo entre paréntesis {} (excepto las variables dentro de otras funciones que están en este ámbito).
  2. Si no puede encontrar la variable dentro del cuerpo de la función , subirá a la cadena y mirará el alcance de la variable en la función en la que se definió la función . Esto es lo que se entiende por alcance léxico, podemos ver en el código donde se definió esta función y, por lo tanto, podemos determinar la cadena de alcance simplemente mirando el código.

Ejemplo:

// global scope var foo = ''global''; var bar = ''global''; var foobar = ''global''; function outerFunc () { // outerFunc scope var foo = ''outerFunc''; var foobar = ''outerFunc''; innerFunc(); function innerFunc(){ // innerFunc scope var foo = ''innerFunc''; console.log(foo); console.log(bar); console.log(foobar); } } outerFunc();

¿Qué pasa cuando estamos tratando de registrar las variables foo, bary foobarque la consola es la siguiente:

  1. Intentamos registrar foo en la consola, foo se puede encontrar dentro de la innerFuncpropia función . Por lo tanto, el valor de foo se resuelve a la cadena innerFunc.
  2. Intentamos registrar la barra en la consola, la barra no se puede encontrar dentro de la función en innerFuncsí. Por lo tanto, tenemos que escalar la cadena de alcance . Primero observamos la función externa en la que innerFuncse definió la función . Esta es la función outerFunc. En el alcance de outerFuncpodemos encontrar la barra de variables, que contiene la cadena ''outerFunc''.
  3. foobar no se puede encontrar en innerFunc. .Por lo tanto, tenemos que escalar la cadena de alcance al ámbito de innerFunc. Tampoco se puede encontrar aquí, subimos otro nivel al alcance global (es decir, el alcance más externo). Encontramos aquí la variable foobar que contiene la cadena ''global''. Si no hubiera encontrado la variable después de escalar la cadena de alcance, el motor JS lanzaría un error de referencia .

ES6 (ES 2015) y mayores:

Los mismos conceptos de alcance léxico y scopechain todavía se aplican en ES6. Sin embargo se introdujeron nuevas formas de declarar variables. Hay los siguientes:

  • let : crea una variable de ámbito de bloque
  • const : crea una variable de ámbito de bloque que se debe inicializar y no se puede reasignar

La mayor diferencia entre vary let/ constes que vares el ámbito de la función, mientras que let/ constson el ámbito del bloque. Aquí hay un ejemplo para ilustrar esto:

let letVar = ''global''; var varVar = ''global''; function foo () { if (true) { // this variable declared with let is scoped to the if block, block scoped let letVar = 5; // this variable declared with let is scoped to the function block, function scoped var varVar = 10; } console.log(letVar); console.log(varVar); } foo();

En el ejemplo anterior, letVar registra el valor global porque las variables declaradas con letámbito de bloque. Dejan de existir fuera de su bloque respectivo, por lo que no se puede acceder a la variable fuera del bloque if.


1) Hay un alcance global, un alcance de función y los ámbitos con y captura. En general, no hay alcance de nivel de "bloque" para las variables: las declaraciones with y catch agregan nombres a sus bloques.

2) Los ámbitos están anidados por funciones hasta el ámbito global.

3) Las propiedades se resuelven pasando por la cadena del prototipo. La instrucción with trae los nombres de las propiedades del objeto al ámbito léxico definido por el bloque with.

EDITAR: ECMAAScript 6 (Harmony) está diseñado para admitir let, y sé que Chrome permite una bandera de ''armonía'', por lo que tal vez sí lo admita ..

Sea un soporte para el alcance a nivel de bloque, pero debe usar la palabra clave para que esto suceda.

EDITAR: En base a lo señalado por Benjamin en las declaraciones with y catch de los comentarios, he editado la publicación y he agregado más. Tanto las declaraciones with como las de catch introducen variables en sus respectivos bloques, y ese es un ámbito de bloque. Estas variables tienen un alias a las propiedades de los objetos pasados ​​en ellas.

//chrome (v8) var a = { ''test1'':''test1val'' } test1 // error not defined with (a) { var test1 = ''replaced'' } test1 // undefined a // a.test1 = ''replaced''

EDITAR: aclarar ejemplo:

test1 está dentro del ámbito con el bloque with, pero tiene un alias de a.test1. ''Var test1'' crea una nueva variable test1 en el contexto léxico superior (función, o global), a menos que sea una propiedad de - que es.

¡Ay! Tenga cuidado al usar ''with''; al igual que var es un noop si la variable ya está definida en la función, ¡también es un noop con respecto a los nombres importados desde el objeto! Un poco de atención sobre el nombre que ya se está definiendo haría esto mucho más seguro. Personalmente nunca usaré con esto debido a esto.


Aquí hay un ejemplo:

<script> var globalVariable = 7; //==window.globalVariable function aGlobal( param ) { //==window.aGlobal(); //param is only accessible in this function var scopedToFunction = { //can''t be accessed outside of this function nested : 3 //accessible by: scopedToFunction.nested }; anotherGlobal = { //global because there''s no `var` }; } </script>

Querrá investigar los cierres y cómo usarlos para hacer miembros privados .


Cada fragmento de código JavaScript (código global o funciones) tiene una cadena de alcance asociada. Esta cadena de alcance es una lista o cadena de objetos que define las variables que están “dentro del alcance” para ese código. Cuando JavaScript necesita buscar el valor de una variable x (un proceso llamado resolución de variable ), comienza mirando el primer objeto de la cadena. Si ese objeto tiene una propiedad llamada x , se usa el valor de esa propiedad. Si el primer objeto no tiene una propiedad llamada x , JavaScript continúa la búsqueda con el siguiente objeto en la cadena. Si el segundo objeto no tiene una propiedad llamada x , la búsqueda pasa al siguiente objeto, y así sucesivamente. Si x no es una propiedad de ninguno de los objetos en la cadena de alcance, entonces x no está en el alcance de ese código, y se produce un error de referencia. En el código de JavaScript de nivel superior (es decir, código no contenido en ninguna definición de función), la cadena de alcance consiste en un solo objeto, el objeto global. En una función no anidada, la cadena de alcance consta de dos objetos. El primero es el objeto que define los parámetros de la función y las variables locales, y el segundo es el objeto global. En una función anidada, la cadena de alcance tiene tres o más objetos. Es importante entender cómo se crea esta cadena de objetos. Cuando una función está DEFINIDA , almacena la cadena de alcance entonces en efecto. Cuando esa función está INVOCADA , crea un nuevo objeto para almacenar sus variables locales y agrega ese nuevo objeto a la cadena de alcance almacenada para crear una nueva cadena más larga que represente el alcance de esa invocación de función. Esto se vuelve más interesante para las funciones anidadas porque cada vez que se llama a la función externa, la función interna se define de nuevo.Dado que la cadena de alcance difiere en cada invocación de la función externa, la función interna será sutilmente diferente cada vez que se defina: el código de la función interna será idéntico en cada invocación de la función externa, pero la cadena de alcance asociada con esa función. El código será diferente . Esta noción de una cadena de alcance es crucial para entender los cierres.


Descubrí que muchas personas nuevas en JavaScript tienen problemas para entender que la herencia está disponible de forma predeterminada en el idioma y que el alcance de la función es el único alcance, hasta el momento. Le proporcioné una extensión a un embellecedor que escribí a fines del año pasado, llamado JSPretty. La función de colores de función funciona en el código y siempre asocia un color a todas las variables declaradas en ese alcance. El cierre se demuestra visualmente cuando una variable con un color de un alcance se usa en un alcance diferente.

Pruebe la función en:

Vea una demostración en:

Ver el código en:

Actualmente, la función ofrece soporte para una profundidad de 16 funciones anidadas, pero actualmente no colorea variables globales.


En "Javascript 1.7" (la extensión de Mozilla a Javascript) también se pueden declarar variables de ámbito de bloque con la instrucción let :

var a = 4; let (a = 3) { alert(a); // 3 } alert(a); // 4


Hay casi dos tipos de ámbitos de JavaScript:

  • el alcance de cada declaración var está asociado con la función de cierre más inmediata
  • Si no hay una función adjunta para una declaración var, es un ámbito global.

Por lo tanto, cualquier bloque que no sea funciones no crea un nuevo ámbito. Eso explica por qué los bucles for sobrescriben las variables de ámbito externo:

var i = 10, v = 10; for (var i = 0; i < 5; i++) { var v = 5; } console.log(i, v); // output 5 5

Usando funciones en su lugar:

var i = 10, v = 10; $.each([0, 1, 2, 3, 4], function(i) { var v = 5; }); console.log(i,v); // output 10 10

En el primer ejemplo, no hubo un ámbito de bloque, por lo que las variables declaradas inicialmente se sobrescribieron. En el segundo ejemplo, hubo un nuevo alcance debido a la función, por lo que las variables inicialmente declaradas se SOMBRARON, y no se sobrescribieron.

Eso es casi todo lo que necesita saber en términos de alcance de JavaScript, excepto:

Así que puedes ver que el alcance de JavaScript es en realidad extremadamente simple, aunque no siempre intuitivo. Algunas cosas a tener en cuenta:

  • Las declaraciones var se elevan a la parte superior del alcance. Esto significa que no importa donde suceda la declaración var, para el compilador es como si la propia varilla sucediera en la parte superior
  • Se combinan múltiples declaraciones var dentro del mismo alcance.

Así que este código:

var i = 1; function abc() { i = 2; var i = 3; } console.log(i); // outputs 1

es equivalente a:

var i = 1; function abc() { var i; // var declaration moved to the top of the scope i = 2; i = 3; // the assignment stays where it is } console.log(i);

Esto puede parecer contrario a la intuición, pero tiene sentido desde la perspectiva de un diseñador de lenguaje imperativo.


JavaScript tiene solo dos tipos de alcance:

  1. Global Scope : Global no es más que un alcance de nivel de ventana. Aquí, variable presente en toda la aplicación.
  2. Alcance funcional : la variable declarada dentro de una función con la palabra clave var tiene un alcance funcional.

Cada vez que se llama a una función, se crea un objeto de alcance de variable (y se incluye en la cadena de alcance) que es seguido por variables en JavaScript.

a = "global"; function outer(){ b = "local"; console.log(a+b); //"globallocal" } outer();

Cadena de alcance ->

  1. Nivel de ventana: a y outer función outer están en el nivel superior en la cadena de alcance.
  2. cuando la función externa llama un nuevo variable scope object (e incluido en la cadena de alcance) agregado con la variable b en su interior.

Ahora, cuando una variable a requiere, primero busca el alcance de la variable más cercana y si la variable no está allí, se mueve al siguiente objeto de la cadena de alcance de la variable. En este caso, el nivel de la ventana es:


Javascript utiliza cadenas de alcance para establecer el alcance de una función determinada. Normalmente hay un alcance global, y cada función definida tiene su propio alcance anidado. Cualquier función definida dentro de otra función tiene un alcance local que está vinculado a la función externa. Siempre es la posición en la fuente que define el alcance.

Un elemento en la cadena de alcance es básicamente un Mapa con un puntero a su alcance principal.

Al resolver una variable, javascript comienza en el ámbito más interno y busca hacia afuera.



La idea del alcance en JavaScript cuando fue diseñado originalmente por Brendan Eich surgió del lenguaje de programación HyperCard HyperTalk .

En este idioma, las pantallas se realizaron de forma similar a una pila de fichas. Había una tarjeta maestra referida como el fondo. Era transparente y puede verse como la carta inferior. Cualquier contenido en esta tarjeta base fue compartido con las tarjetas colocadas encima de esta. Cada tarjeta colocada en la parte superior tenía su propio contenido que tenía prioridad sobre la tarjeta anterior, pero aún así tenía acceso a las tarjetas anteriores, si así lo deseaba.

Así es exactamente cómo se diseña el sistema de alcance de JavaScript. Simplemente tiene nombres diferentes. Las tarjetas en JavaScript son conocidas como Contextos de Ejecución ECMA . Cada uno de estos contextos contiene tres partes principales. Un entorno variable, un entorno léxico y este enlace. Volviendo a la referencia de las tarjetas, el entorno léxico contiene todo el contenido de las tarjetas anteriores más abajo en la pila. El contexto actual se encuentra en la parte superior de la pila y cualquier contenido declarado allí se almacenará en el entorno variable. El entorno variable tendrá prioridad en el caso de nombrar colisiones.

Este enlace apuntará al objeto contenedor. A veces, los ámbitos o contextos de ejecución cambian sin que cambie el objeto que contiene, como en una función declarada donde el objeto que contiene puede ser una window o una función de constructor.

Estos contextos de ejecución se crean cada vez que se transfiere el control. El control se transfiere cuando el código comienza a ejecutarse, y esto se realiza principalmente desde la ejecución de la función.

Esa es la explicación técnica. En la práctica, es importante recordar que en JavaScript

  • Los ámbitos son técnicamente "Contextos de ejecución"
  • Los contextos forman una pila de entornos donde se almacenan las variables.
  • La parte superior de la pila tiene prioridad (la parte inferior es el contexto global)
  • Cada función crea un contexto de ejecución (pero no siempre un nuevo enlace).

Aplicando esto a uno de los ejemplos anteriores (5. "Cierre") en esta página, es posible seguir la pila de contextos de ejecución. En este ejemplo hay tres contextos en la pila. Están definidos por el contexto externo, el contexto en la función inmediatamente invocada llamada por var seis, y el contexto en la función devuelta dentro de la función inmediatamente invocada de var seis.

i ) El contexto exterior. Tiene un entorno variable de a = 1.
ii ) El contexto IIFE, tiene un entorno léxico de a = 1, pero un entorno variable de a = 6 que tiene prioridad en la pila
iii ) El contexto de la función devuelta, tiene un entorno léxico de a = 6 y ese es el valor al que se hace referencia en la alerta cuando se llama.


Las variables declaradas globalmente tienen un alcance global. Las variables declaradas dentro de una función están sujetas a esa función, y sombrean las variables globales del mismo nombre.

(Estoy seguro de que hay muchas sutilezas que los programadores reales de JavaScript podrán señalar en otras respuestas. En particular, encontré esta página sobre lo que this significa exactamente en cualquier momento. Esperamos que este enlace más introductorio sea ​​suficiente para comenzar. aunque.)


Pienso que lo mejor que puedo hacer es darte un montón de ejemplos para estudiar. Los programadores de Javascript están prácticamente clasificados por lo bien que entienden el alcance. A veces puede ser bastante contraintuitivo.

  1. Una variable de ámbito global

    // global scope var a = 1; function one() { alert(a); // alerts ''1'' }

  2. Alcance local

    // global scope var a = 1; function two(a) { // passing (a) makes it local scope alert(a); // alerts the given argument, not the global value of ''1'' } // local scope again function three() { var a = 3; alert(a); // alerts ''3'' }

  3. Intermedio : no existe el alcance del bloque en JavaScript (ES5; ES6 introduce let )

    a.

    var a = 1; function four() { if (true) { var a = 4; } alert(a); // alerts ''4'', not the global value of ''1'' }

    segundo.

    var a = 1; function one() { if (true) { let a = 4; } alert(a); // alerts ''1'' because the ''let'' keyword uses block scoping }

  4. Intermedio : propiedades del objeto

    var a = 1; function Five() { this.a = 5; } alert(new Five().a); // alerts ''5''

  5. Avanzado : Cierre

    var a = 1; var six = (function() { var a = 6; return function() { // JavaScript "closure" means I have access to ''a'' in here, // because it is defined in the function in which I was defined. alert(a); // alerts ''6'' }; })();

  6. Avanzado : resolución de alcance basada en prototipo

    var a = 1; function seven() { this.a = 7; } // [object].prototype.property loses to // [object].property in the lookup chain. For example... // Won''t get reached, because ''a'' is set in the constructor above. seven.prototype.a = -1; // Will get reached, even though ''b'' is NOT set in the constructor. seven.prototype.b = 8; alert(new seven().a); // alerts ''7'' alert(new seven().b); // alerts ''8''

  7. Global + Local : Un caso extra complejo

    var x = 5; (function () { console.log(x); var x = 10; console.log(x); })();

    Esto imprimirá undefined y 10 lugar de 5 y 10 ya que JavaScript siempre mueve las declaraciones de variables (no las inicializaciones) a la parte superior del alcance, haciendo que el código sea equivalente a:

    var x = 5; (function () { var x; console.log(x); x = 10; console.log(x); })();

  8. Captura de la cláusula de la cláusula de captura

    var e = 5; console.log(e); try { throw 6; } catch (e) { console.log(e); } console.log(e);

    Esto imprimirá 5 , 6 , 5 . Dentro de la cláusula catch e sombrea variables globales y locales. Pero este ámbito especial es solo para la variable capturada. Si escribes var f; Dentro de la cláusula catch, entonces es exactamente lo mismo que si lo hubieras definido antes o después del bloque try-catch.


Sólo hay ámbitos de funciones en JS. ¡No bloquees los alcances! Puedes ver lo que está levantando también.

var global_variable = "global_variable"; var hoisting_variable = "global_hoist"; // Global variables printed console.log("global_scope: - global_variable: " + global_variable); console.log("global_scope: - hoisting_variable: " + hoisting_variable); if (true) { // The variable block will be global, on true condition. var block = "block"; } console.log("global_scope: - block: " + block); function local_function() { var local_variable = "local_variable"; console.log("local_scope: - local_variable: " + local_variable); console.log("local_scope: - global_variable: " + global_variable); console.log("local_scope: - block: " + block); // The hoisting_variable is undefined at the moment. console.log("local_scope: - hoisting_variable: " + hoisting_variable); var hoisting_variable = "local_hoist"; // The hoisting_variable is now set as a local one. console.log("local_scope: - hoisting_variable: " + hoisting_variable); } local_function(); // No variable in a separate function is visible into the global scope. console.log("global_scope: - local_variable: " + local_variable);


Solo para agregar a las otras respuestas, el alcance es una lista de búsqueda de todos los identificadores (variables) declarados, y aplica un conjunto estricto de reglas en cuanto a cómo estos son accesibles al código que se está ejecutando actualmente. Esta búsqueda puede ser con el propósito de asignar a la variable, que es una referencia LHS (lado izquierdo), o puede ser con el propósito de recuperar su valor, que es una referencia RHS (lado derecho). Estas búsquedas son lo que hace el motor de JavaScript internamente cuando compila y ejecuta el código.

Entonces, desde esta perspectiva, creo que una imagen ayudaría a encontrarla en el libro electrónico Scopes and Closures de Kyle Simpson:

Citando de su ebook:

El edificio representa el conjunto de reglas de alcance anidado de nuestro programa. El primer piso del edificio representa su ámbito de ejecución actual, esté donde esté. El nivel superior del edificio es el alcance global. Resuelve las referencias de LHS y RHS al buscar en su piso actual, y si no lo encuentra, tome el ascensor hasta el siguiente piso, mirando hacia allí, luego al siguiente, y así sucesivamente. Una vez que llegas al último piso (el alcance global), encuentras lo que estás buscando o no. Pero tienes que parar sin importar.

Una cosa a destacar que vale la pena mencionar, "la búsqueda de alcance se detiene una vez que encuentra la primera coincidencia".

Esta idea de "niveles de alcance" explica por qué "esto" se puede cambiar con un alcance creado recientemente, si se está buscando en una función anidada. Aquí hay un enlace que incluye todos estos detalles, todo lo que quería saber sobre el alcance de javascript.


ejecuta el codigo Espero que esto le dé una idea sobre el alcance

Name = ''global data''; document.Name = ''current document data''; (function(window,document){ var Name = ''local data''; var myObj = { Name: ''object data'', f: function(){ alert(this.Name); } }; myObj.newFun = function(){ alert(this.Name); } function testFun(){ alert("Window Scope : " + window.Name + "/nLocal Scope : " + Name + "/nObject Scope : " + this.Name + "/nCurrent document Scope : " + document.Name ); } testFun.call(myObj); })(window,document);


En JavaScript hay dos tipos de alcance:

  • Alcance local
  • Alcance global

La función Abajo tiene una variable de alcance local carName. Y esta variable no es accesible desde fuera de la función.

function myFunction() { var carName = "Volvo"; alert(carName); // code here can use carName }

La clase debajo tiene una variable de alcance global carName. Y esta variable es accesible desde cualquier parte de la clase.

class { var carName = " Volvo"; // code here can use carName function myFunction() { alert(carName); // code here can use carName } }


Global: variable declarada fuera de una función

Local: variable declarada dentro de una función, y solo se puede llamar en ese ámbito


Hay dos tipos de ámbitos en JavaScript.

  1. Alcance global : la variable que se anuncia en el alcance global se puede utilizar en cualquier parte del programa sin problemas. Por ejemplo:

    var carName = " BMW"; // code here can use carName function myFunction() { // code here can use carName }

  2. Ámbito funcional o Ámbito local : la variable declarada en este ámbito solo se puede utilizar en su propia función. Por ejemplo:

    // code here can not use carName function myFunction() { var carName = "BMW"; // code here can use carName }


ECMAScript 6 introdujo las palabras clave let y const. Estas palabras clave se pueden utilizar en lugar de la palabra clave var. Al contrario de la palabra clave var, las palabras clave let y const admiten la declaración de alcance local dentro de las declaraciones de bloque.

var x = 10 let y = 10 const z = 10 { x = 20 let y = 20 const z = 20 { x = 30 // x is in the global scope because of the ''var'' keyword let y = 30 // y is in the local scope because of the ''let'' keyword const z = 30 // z is in the local scope because of the ''const'' keyword console.log(x) // 30 console.log(y) // 30 console.log(z) // 30 } console.log(x) // 30 console.log(y) // 20 console.log(z) // 20 } console.log(x) // 30 console.log(y) // 10 console.log(z) // 10


En EcmaScript5, existen principalmente dos ámbitos, el alcance local y el alcance global, pero en EcmaScript6 tenemos principalmente tres ámbitos, el alcance local, el alcance global y un nuevo ámbito denominado bloque de alcance .

Ejemplo de ámbito de bloque es: -

for ( let i = 0; i < 10; i++) { statement1... statement2...// inside this scope we can access the value of i, if we want to access the value of i outside for loop it will give undefined. }


Mi entendimiento es que hay 3 ámbitos: alcance global, disponible globalmente; alcance local, disponible para una función completa independientemente de los bloques; y ámbito de bloque, solo disponible para el bloque, la declaración o la expresión en la que se usó. El alcance global y local se indican con la palabra clave ''var'', ya sea dentro de una función o fuera, y el alcance del bloque se indica con la palabra clave ''dejar''.

Para aquellos que creen que solo hay un alcance global y local, explique por qué Mozilla tendría una página completa que describe los matices del alcance del bloque en JS.

let


Prueba este curioso ejemplo. En el siguiente ejemplo, si a se hubiera inicializado numéricamente en 0, vería 0 y luego 1. Excepto que a es un objeto y javascript pasará f1 un puntero de a en lugar de una copia de él. El resultado es que obtienes la misma alerta en ambas ocasiones.

var a = new Date(); function f1(b) { b.setDate(b.getDate()+1); alert(b.getDate()); } f1(a); alert(a.getDate());