2012-07-02 19 views
5

Recientemente, mientras leía un libro muy bueno; 'Maintainable Javascript', descubrí el uso del pragma "use strict".Modo estricto en un espacio de nombres con Javascript

El "uso estricto" parece ser una mala práctica si se declara en el ámbito global. El método recomendado es utilizar el modo estricto directamente en cada función como esta:

// Non-strict code... 

(function(){ 
    "use strict"; 

    // Define your library strictly... 
})(); 

// Non-strict code... 

¿Es posible definir el modo estricto a todo un espacio de nombres en lugar de definir en cada función? Si es así, ¿puedo tener una o dos muestras de código?

Gracias.

Respuesta

5

modo estricto se aplica al contexto de ejecución en el que se declaró y todos los contextos ese contexto contiene (con un poco de squidginess alrededor de contextos creados a través de eval, pero evitar el uso de eval y evitar la squidginess), por lo general tendrá que utilizar el patrón de módulo para aplicarla a todo el código:

(function() { 
    "use strict"; 

    function foo() { 
    } 

    function bar() { 
    } 

    // ...presumably code hooking up `foo` and `bar` to events 
    // or otherwise using them -- or of course, you could export 
    // them from the scope... 
})(); 

En el modo anterior, el estricto se aplica no sólo a la función anónima, pero a foo y bar también. Así, por ejemplo, donde el código sería "trabajo" (crear una variable global a través de The Horror of Implicit Globals):

(function() { 
    function foo() { 
     someNameThatIsntDefined = 42; // Blech, creates implicit global 
    } 

    foo(); 
})(); 

... este código falla con un ReferenceError (el único cambio es el "use strict"):

(function() { 
    "use strict"; 

    function foo() { 
     someNameThatIsntDefined = 42; // Throws ReferenceError 
    } 

    foo(); 
})(); 

... porque una de las muchas cosas útiles que hace el modo estricto es deshacerse del horror de los globales implícitos.

Aquí hay otro ejemplo, donde se exportan una función que se ejecuta en modo estricto, incluso cuando se llama desde código no estricto:

var MyModule; 
MyModule = MyModule || {}; 
(function(mod) { 
    "use strict"; 

    mod.doSomethingUseful = doSomethingUseful; 
    function doSomethingUseful() { 
     // ... 
    } 

})(MyModule); 

código "suelta" puede llamar MyModule.doSomethingUseful, que siempre se ejecuta en modo estricto. El resultado es que puede aplicar el modo estricto a su código sin requerir que todos usando su código también lo use. Muy útil, eso.

+0

Gracias por la edición, Matt! Hago eso (cadena en lugar de estricto) mucho ... :-) –

0

La primera forma es cuando pone "use strict"; pragma en la primera línea del archivo .js. Entonces TODO en ese archivo será estrictamente evaluado.
No hay nada inherentemente malo en eso. Tarde o temprano todos los navegadores harán obsoleto el "viejo código js". La única desventaja real podría ser romper el código antiguo si lo usa.

Segunda forma podría ser un objeto de esta manera:

tmp = new o.Pixel (300, 300);

} // end 

Ese código le permite tener variables "privadas". Tenga en cuenta que f también como una 'privada' var.

uso es simple:

var rvar = contName.rnd(5); 
var obj = new contName.Pixel(300, 300) 

Tercera forma podría ser T.J.Crowder de, cuarta es Doug Crockford ... Estos son sólo diferentes formas para emular algo que todavía no está oficialmente presente en un idioma.

+0

'var contName = new function() {...' Ese constructo no hace lo que crees que hace. Y el OP señaló que creía que había razones para no usarlo globalmente. (No sé cuáles son, ya que nunca hago ** nada ** globalmente ...) Y el nombre de Crockford es "Douglas" (o "Doug"). –

+0

Crea un objeto. Nombre corregido;) – CoR

+1

Correcto, crea un objeto. Usando el 'prototipo' de la función anónima que está definiendo como parte de la expresión. Es una forma indirecta y engañosa de crear un objeto. –

0
var Module = (function() { 
    "use strict"; 

    var f = function() { 
     // do stuff 
    } 

    return { // return your namespace 
     "myModuleFunction": f 
    } 
})(); 

Creo que esto debería funcionar también.

Cuestiones relacionadas