2012-08-14 26 views
5

después de mi última pregunta, ésta es más preciso para mí:variables “var”, "este" variables y variables "globales" - dentro de un JavaScript Constructor

ejemplo:

function Foo() { 
    this.bla = 1; 
    var blabla = 10; 
    blablabla = 100; 
    this.getblabla = function() { 
     return blabla; // exposes blabla outside 
    } 
} 
foo = new Foo(); 

lo que Comprenda ahora:

this.bla = 1;  // will become an attribute of every instance of FOO. 
var blabla = 10; // will become a local variable of Foo(will **not** become an attribute of every instance of FOO), which could be accessed by any instance of FOO - only if there's a method like "this.getBlabla". that's a "closer" ? 
blablabla = 100; // will define a **new** (or change if exist) global(window) variable. 

¿Entiendo correctamente?

Además, si incluyo var blabla = 10; y la función getblabla que lo usa en el contratista, entonces para cada instancia de Foo ("foo" ...), se guardará una función de contratista Foo en la memoria que incluye este variable "privada". o será la misma función Foo que el lugar para las variables privadas - para TODAS las instancias (como "foo") de Foo?

+0

Sus primeras tres afirmaciones son correctas. No sigo completamente lo que está preguntando por su última pregunta. ¿Puedes aclarar?¿Puedes probar variables no nombradas de manera similar? Es difícil de seguir. Gracias. – Brad

+0

También es complicado para mí. Quiero decir, es un cierre, ¿verdad? y es un contratista, entonces, ¿por cada instancia de Foo, habrá un nuevo cierre de Foo en la memoria? ¿Cómo funciona esto? Gracias. – Daniel

Respuesta

6

Sólo para centrarse en el alcance, voy a ejecutar este ejemplo, (con clara variables) Después, lo conectaré nuevamente a sus variables.

var x = "Global scope"; 
var y = "Not changed."; 

function Foo() { 
    this.x = "Attribute of foo"; 
    var x = "In foo's closure"; 
    y = "Changed!" 
    this.getX = function() { 
     return x; 
    } 
} 

// do some logging 

console.log(x); // "Global scope" 
console.log(y); // "Not changed" 
foo = new Foo(); 
console.log(y); // "Changed!" 
console.log(foo.x); // "Attribute of foo" 
console.log(x); // "Global scope" 
console.log(foo.getX()); // "In foo's closure" 

La línea: this.x es equivalente a this.bla, y se define un atributo disponible externamente de un objeto Foo. y es equivalente a blablabla=100 y luego el x dentro de foo es equivalente a su blablabla dentro de foo. Aquí hay un jsfiddle realmente áspero que puedes ejecutar para ver esto.

1

Sí, lo entiendes!
En cuanto a la segunda parte de la pregunta, se trata de herencia, al igual que la relación entre la ventana (global) y las funciones definidas en su alcance (raíz de pensar). Entonces todo lo que no se vuelva a especificar, se buscará en el antepasado.

Esto es tremendous good video por Crockford, quien lo explica REALMENTE bien.

2

Todo lo que ha dicho es correcto. (Por supuesto, un error será lanzado en la asignación de blablabla en Strict Mode.

En la segunda mitad, no hay nada especial acerca de la función constructora. Simplemente actúa como cualquier otra función ya que crea un cierre que persiste mientras . como su referencia (la vida útil de this.getblabla en este caso)

Tome este ejemplo:

function initBlaBla() { 
    var blabla = 10; 
    this.getblabla = function() { 
     return blabla; // exposes blabla outside 
    } 
} 

function Foo() { 
    this.bla = 1; 
    blablabla = 100; 
    initBlaBla.call(this); 
} 

foo = new Foo(); 

Aquí, el constructor Foo no forma un cierre y su alcance se libera inmediatamente initBlaBla por el otro. han d crea un cierre. Curiosamente, el compilador puede ver que blabla nunca se escribe y optimiza this.getblabla para devolver siempre 10 y nunca guardar el alcance de cierre. Esto se puede ver cuando rompe la ejecución en una función dentro de un cierre e intenta leer un valor que no hace referencia internamente.

El alcance de cierre conseguirá puesto en libertad y en cola para la recolección de basura si se llama a cualquiera de los siguientes:

delete foo.getblabla; 
foo.getblabla = "Anything!"; 
foo = "Anything else.";