Pregunta

Hoy tuve una discusión con un colega sobre funciones anidadas en Javascript:

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   d = 'Bound to global object.'
}

En este ejemplo, las pruebas señalan que b no es alcanzable fuera del cuerpo de a, al igual que c es. Sin embargo, d es - después de ejecutar un (). Busque la definición exacta de este comportamiento en ECMAScript v. 3 estándar , no encontré la redacción exacta que estaba buscando; lo que Sec.13 p.71 no dice, es a qué objeto se debe vincular el objeto de función creado por la declaración de la función. ¿Me estoy perdiendo algo?

¿Fue útil?

Solución

Este es el alcance estático. Las declaraciones dentro de una función están dentro del alcance de esa función.

Javascript tiene un comportamiento peculiar, sin embargo, es que sin la palabra clave var , ha implicado una variable global . Eso es lo que estás viendo en tu prueba. Tu " d " La variable está disponible porque es una global implícita, a pesar de estar escrita dentro del cuerpo de una función.

También, para responder a la segunda parte de su pregunta: existe una función en el ámbito que se declara, como una variable.

Sidenote: Probablemente no desee variables globales, especialmente no implícitas. Se recomienda que siempre use la palabra clave var para evitar confusiones y mantener todo limpio.

Sidenote: El estándar ECMA no es probablemente el lugar más útil para encontrar respuestas sobre Javascript, aunque ciertamente no es un mal recurso. Recuerde que javascript en su navegador es solo una implementación de ese estándar, por lo que el documento de estándares le dará las reglas que fueron (en su mayoría) seguidas por los implementadores cuando se construyó el motor de javascript. No puede ofrecer información específica sobre las implementaciones que le interesan, es decir, los principales navegadores. Hay un par de libros en particular que te darán información muy directa sobre cómo se comportan las implementaciones de JavaScript en los principales navegadores. Para ilustrar la diferencia, incluiré extractos a continuación de la especificación ECMAScript y un libro en Javascript. Creo que estará de acuerdo en que el libro da una respuesta más directa.

Aquí encontrará la Especificación del lenguaje ECMAScript :

  

10.2 Ingresando un contexto de ejecución

     

Cada función y llamada de constructor   Entra en un nuevo contexto de ejecución, incluso   Si una función se llama a sí misma   recursivamente. Cada retorno sale de un   contexto de ejecución Una excepción lanzada,   Si no es capturado, también puede salir de uno o   Más contextos de ejecución.

     

Cuando el control   Entra en un contexto de ejecución, el ámbito de aplicación.   La cadena se crea y se inicializa,   Se realiza una instanciación variable,   y se determina este valor.

     

El   Inicialización de la cadena de alcance,   instanciación variable, y la   La determinación de este valor depende.   sobre el tipo de código que se ingresa.

Aquí está de O'Reilly's Javascript: La guía definitiva (5a edición) :

  

8.8.1 Alcance léxico

     

Las funciones en JavaScript son léxicamente   En lugar de un ámbito dinámico. Esta   significa que se ejecutan en el ámbito de aplicación en   que se definen, no el alcance   a partir de la cual se ejecutan. Cuando un   Se define la función, el alcance actual.   La cadena se guarda y se convierte en parte de.   El estado interno de la función.   ...

Muy recomendable para cubrir este tipo de preguntas es el libro de Douglas Crockford:

JavaScript, The Good Parts http://oreilly.com/catalog/covers/9780596517748_cat.gif

Javascript, The Good Parts , también de O 'Reilly.

Otros consejos

Según tengo entendido, estos son equivalentes en lo que respecta al alcance:

function a() { ... }

y

var a = function() { ... }

Parece importante tener en cuenta que, mientras que d se crea como un "global", en realidad se crea como una propiedad del objeto de ventana. Esto significa que podría estar sobrescribiendo inadvertidamente algo que ya existe en el objeto de la ventana o su variable podría fallar en su creación. Entonces:

function a() {
    d = 'Hello World';
}
alert(window.d); // shows 'Hello World'

Pero no puedes hacer:

function a() {
    document = 'something';
}

porque no puede sobrescribir el objeto window.document.

Para todos los propósitos prácticos, puede imaginar que todo su código se está ejecutando en un gigante con (ventana) .

Javascript tiene dos ámbitos. Global y funcional. Si declara una variable dentro de una función utilizando " var " palabra clave, será local para esa función y cualquier función interna. Si declara una variable fuera de una función, tiene un alcance global.

Finalmente, si omite la palabra clave var al declarar por primera vez una variable, javascript asume que desea una variable global, sin importar dónde la declare .

Entonces, estás llamando a la función a, y la función a está declarando una variable global d.

...

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   d = 'Bound to global object.'
}

sin estar precedido por var , d es global. Haga esto para hacer d privado:

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   var d = 'Bound to local object.'
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top