2011-06-13 12 views
8

Soy un poco nuevo en JavaScript, así que tengan paciencia si esta es una pregunta tonta.Pregunta sobre la eficacia del cierre/encapsulado en JavaScript

Digamos que tengo una "clase" que tiene este aspecto:

var obj = function() { 
    var val; 
    return { 
     setVal: function(newVal) { 
      val = newVal; 
     }, 
     getVal: function() { 
      return val; 
     } 
    }; 
}; 

Suponiendo que mi sintaxis es correcta, esto define una clase con una propiedad "privada" llamado "valor", con métodos para establecer/obtener la propiedad. Ahora, voy a crear dos objetos de esta clase:

var myObj = obj(); 
var yourObj = obj(); 

¿Este a crear un método GETVAL() setval separado() y para cada objeto? ¿Si no, porque no? Si es así, ¿es esto una preocupación seria al construir aplicaciones web eficientes? ¿Valdrá la pena la compensación (si existe) de la eficacia del cierre en la mayoría/todos los contextos? ¿Soy tonto?

Gracias, Gerard

+0

aquí hay un buen artículo sobre cierres y creación de prototipos. http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closures – ScottE

+0

Esta es una pregunta excelente para preguntar si acaba de comenzar en javascript. – Zoidberg

Respuesta

0

que sí hace de manera conceptual. Sin embargo, dado que este es un patrón tan común, los JIT de JavaScript modernos saben cómo optimizarlo para que solo haya una copia del código almacenada en la memoria, con las redirecciones de puntero apropiadas para que funcione con el cierre relevante.

EDITAR: aunque realmente no estoy preparado para la especulación a través del código fuente, aquí hay algunas pruebas básicas. Download the Chrome dev channel release, y tomar instantáneas del montón antes y después de ejecutar el siguiente código:

var obj = /* as above */; 

var objs = []; 
for (var i = 0; i < 10000; ++i) { 
    objs.push(obj()); 
} 

luego hacer lo mismo para este código:

function Obj() { } 
Obj.prototype.setVal = function (value) { this._val = value; }; 
Obj.prototype.getVal = function() { return this._val; }; 

var objs = []; 
for (var i = 0; i < 10000; ++i) { 
    objs.push(new Obj()); 
} 

Encontrará las instantáneas del montón para mostrar los mismos números para "Código "en ambos casos, de hecho, la optimización que describo se está realizando.

+0

Aún crea dos instancias de métodos 'setVal' y' getVal' – Raynos

+0

Sí, en JavaScript que es verdadero. Pero no hay pérdida de eficiencia porque en el nivel de código de máquina que compilan los JIT modernos, solo hay una instancia de cada uno. – Domenic

+1

haz una copia de seguridad con enlaces a la fuente V8 y Jaegermonkey. Me imagino que hay múltiples instancias de todas esas funciones, cada una con punteros al contexto de Cierre correcto. Si en realidad solo hay dos funciones, eso es realmente impresionante como una optimización – Raynos

3
var obj = function() { 
    var val; 
    return { 
     setVal: function(newVal) { 
      val = newVal; 
     }, 
     getVal: function() { 
      return val; 
     } 
    }; 
}; 

lo que hace esta función es la siguiente:

  • crear variable llamada val
  • crear nuevo objeto
  • crear una nueva función y asignarla al campo setVal
  • crear un nuevo función y asignarlo al campo getVal
  • return object.

Así que siempre estás creando 4 cosas nuevas.

Esto no es realmente un problema si tiene menos de 1000 objetos en la página. Refactorizarlo es una micro optimización.

La alternativa sería no confiar en las variables locales y usar this._val para indicar que val es privado.