2010-11-03 10 views
7

¿Cuál es la mejor práctica, que resulta en un mejor rendimiento?Cierre de JavaScript vs. variable global

ACTUALIZACIÓN: jsperf.com informa que (a) es más rápido @http://jsperf.com/closure-vs-global-variable

a) utilizar un cierre

var obj = { 
    init: function() { 
     var self = this; 
     $('#element').click(function() { 
      self.clickEvent(); 
     }); 
    }, 
    clickEvent: function() { 
     this.miscMethod(); 
    }, 
    miscMethod: function() {} 
}; 

b) utilizando la variable global

var obj = { 
    init: function() { 
     // removed self=this closure 
     $('#element').click(this.clickEvent); // simple method handler 
    }, 
    clickEvent: function() { 
     obj.miscMethod(); // global variable used 
    }, 
    miscMethod: function() {} 
}; 
+0

El código es una sintaxis no válida. – SLaks

+0

Consulte mi respuesta, y también este enlace: http://javascript.crockford.com/private.html. Explica más sobre cómo funcionan los cierres. – JustcallmeDrago

+0

http://jsperf.com/closure-vs-global-variable/5 me dice que (b) es más rápido. ¿Qué nos enseña eso sobre jsperf.com? – user123444555621

Respuesta

4

ambos deben realizar (casi) idénticamente.

La mejor práctica es evitar los globales.

+0

Gracias, ¿pueden dar más detalles? Pensé que era mejor evitar las variables globales, no había oído que también se aplica a su uso dentro de los métodos. ¿Hay alguna razón para eso? –

+0

+1 Los métodos DOM proporcionados por jQuery superarán por un margen * enorme * las diferencias de rendimiento que pueda detectar en las dos versiones anteriores. – Hamish

+0

@Matty: ¿Qué quieres decir? – SLaks

0

En la mayoría de los navegadores, no hay una diferencia de rendimiento significativa; sin embargo, Chrome parece sufrir un 75% slowdown usando this (corrija mi prueba de rendimiento rápido si me equivoco). Probablemente el principal problema de las mejores prácticas es que a veces puede no estar claro a qué objeto se refiere el objeto this.

En cuanto a declarar (o usar sin declarar) sus propias variables globales, le llamamos espacio de nombre global "contaminación" si usamos demasiadas de ellas. Esto puede llevar a que diferentes partes del código JavaScript interfieran entre sí, lo que evita una buena encapsulación utilizando cierres o "espacios de nombres". La mejor práctica es usar solo como máximo una o dos variables globales. Por ejemplo, jQuery usa solo dos: jQuery y $ (este último se puede desactivar si entra en conflicto con otra biblioteca).

0

1) Dado que las variables globales son peligrosas, considere poner nombres de variables globales en mayúsculas para que sean obvias para cualquier persona (incluido usted) que esté leyendo el código.

2) su primer fragmento no es válido.

function obj = { 
    // your object stuff 
} 

debería ser

var obj = { 
    // your object stuff 
} 

Adicionalmente, no es en realidad un cierre. Así es como implementa un singleton en Javascript.

var mySingleton = (function() { 
    var privateVar = "foo"; 

    function privateFunction() { //this function can only be accessed by other private 
           //and privaleged functions defined in this closure 
     // do stuff. 
    } 

    //stuff to run immediately that will also have access to private variables/functions 

    singletonObj = { 
     key1:"value1", 
     key2:"value2", 
     privilgedFunction: function() { // this method is accessible from the outside 
      // do stuff. you can access private variables in here 
     } 
    }; 

    return singletonObj; //return the object that you just created 
}()); //immediately execute the function, returning an object with private variables 

Estoy asignando el resultado de una función que ejecuto inmediatamente a una variable. Esa función devuelve un objeto, por lo tanto, estoy asignando un objeto a esa variable. PERO ese objeto también tiene miembros privados y funciones privadas.

+0

Es un cierre, no se requiere un patrón singleton para formar un cierre. El contexto de ejecución de la función anónima en (a) se almacena y tiene acceso a sus variables de función externas (auto) ... es decir. un cierre. –

+0

¡Oh, pensé que tu "cierre" era tu función 'obj = {}'! – JustcallmeDrago

1

El problema con su código de cierre es que no funcionará en todos los casos. Si lo hace:

obj.clickEvent() 

entonces funcionará. Pero si lo hace:

var f = obj.clickEvent; 
//hundreds of lines of code 
f(); 

entonces no, como this no hará referencia a obj en esa llamada a la función. Si pasa inmediatamente obj a algo que no lo usa de una manera extraña, entonces no tendrá ese problema, entonces estará "más limpio" ... pero aún creo que es muy fácil cometer errores, entonces recomiendo el enfoque de variable global.

+0

Tampoco funcionará porque 'clickEvent()' no devuelve nada. – SLaks

+0

@SLaks: ah ty, error de escritura fijo – Claudiu