tutorial smart programar para inteligentes inteligente español ejemplos crear contratos contrato aprender javascript jquery design-patterns globals

javascript - smart - solidity español



¿Qué se entiende por "filtrar" en el ámbito global? (4)

"Filtración" en el ámbito global es cuando algo utilizado en un ámbito local se pone a disposición del alcance global de forma involuntaria. Eso significa asignar a una variable que aún no está definida en el alcance actual:

function myFunction() { a=1; } myFunction(); alert(a); //-> 1

Es malo porque podría haber nombres de colisiones que resulten en variables con valores / tipos diferentes de lo esperado. También puede provocar un error en Internet Explorer antiguos cuando se olvida de usar la palabra clave var para una variable utilizada en una declaración for .

No clasificaría intencionalmente una variable global como "fugas", porque es más como si estuvieras "vertiéndola" en el ámbito global. Sin embargo, esto todavía es a menudo considerado como una mala práctica por algunos (aunque creo que es un poco melodramático) porque todavía hay posibles colisiones de nombres con las propiedades actuales del objeto de window , o variables establecidas por otros scripts y bibliotecas.

Hace un tiempo, ofrecí un patrón de diseño de JavaScript (el patrón del módulo, ver más abajo) que obtuve de un ejemplo de John Resig como parte de una solución a la pregunta de alguien y recibí el siguiente comentario:

"... ese patrón está un poco sobre diseñado y no tan bueno. Todavía se está filtrando en el ámbito global. y no te estás abriendo a los cargadores asíncronos. ¡Pero es mejor que solo la codificación ad-hoc! ”

Asi que…

Si "filtrar" en el ámbito global significa que "su objeto se agrega a la ventana del navegador (objeto)" ... entonces todo ya se agrega (globalmente):

Esto "filtra" en el alcance global:

window.jQuery

... simplemente llame: window.jQuery y se resuelve como una función ();

Esto "filtra" en el alcance global:

function HelloWorld() { alert(‘Howdy’); }

… Solo llama: window.HelloWorld() y obtendrás ''Howdy''.

Esto "filtra" en el alcance global:

var myVariable = 10;

… Solo llama: window.myVariable y obtendrás 10

Si el comentarista es correcto, entonces todo lo anterior se “filtra” al alcance global. Así que, personalmente, no veo una manera de NO "filtrarse" en el ámbito global, ya que incluso los controles de formulario existen allí (también).

Como tal, aquí están mis preguntas ...

  • ¿Qué se entiende por "filtración" en el ámbito global?
  • ¿Por qué es tan malo?
  • ¿Cómo lo evitas?
  • Al querer crear objetos personalizados persistentes, ¿por qué es malo el patrón del módulo (abajo)?
  • Los patrones de diseño le permiten encapsular lógica compleja, ¿ es la encapsulación repentinamente mala simplemente porque estamos escribiendo en JavaScript ?
  • O ... ¿este comentarista está simplemente equivocado?

Aquí está el patrón del módulo que mencioné arriba:

<script type="text/javascript"> var myNamespace = (function($) { var publicInstances = {}; // *********************** // myObject publicInstances.myObject = myObject; function myObject() { /// <summary>A pointer to this</summary> var self = this; this.someProperty = new String(); this.initialize = function() { /// your code here } this.someMethod = function() { /// your code here } self.initialize(); } return publicInstances; })(jQuery); jQuery(document).ready(function() { // Use would look like var myInstance = new myNamespace.myObject(); }); </script> ACTUALIZADO :
Estoy satisfecho con las respuestas a continuación y quiero agradecer a todos por tomarse el tiempo para comentar.

Para recapitular las siguientes respuestas:
La "filtración" en el ámbito global se produce cuando algo utilizado en el ámbito local se pone a disposición del alcance global (por ejemplo, el objeto de la ventana). Esto es malo porque abre la página a posibles colisiones de nombres, lo que podría resultar en que las variables se resuelvan en valores o tipos inesperados.

Intencionalmente hacer una variable global no se considera una "fuga". Sin embargo, se requiere que el espacio del nombre del objeto sea adecuado para reducir el potencial de dichas colisiones de nombres.

No puede evitar las variables de alcance global, pero puede reducir los riesgos anteriores utilizando cargadores asíncronos y módulos de definición disponibles en complementos como RequireJS o Curl .


Ejemplo de cargador usando RequireJS :

Defina un módulo de utilidades en utils.js:

define(function () { return { each: function (iterable, callback) { // ... }, map: function (iterable, mapper) { // ... } }; });

Use el módulo anterior en otro módulo, digamos math.js:

define([ "utils" ], function (utils) { return { sum: function (numbers) { var sum = 0; utils.each(numbers, function (n) { sum += n; }); return sum; }, average: function (numbers) { return this.sum(numbers) / numbers.length; } }; });

Y puede usar math.js en otro archivo, digamos main.js:

console.log("About to add 1-3"); require([ "math" ], function (math) { console.log(math.sum([ 1, 2, 3 ])); });

Aún puede tener espacios de nombres, y aún así mantenerlos cálidos y acogedores dentro de los módulos:

namespace.js:

define([ "foo", "bar", "moo" ] function (foo, bar, moo) { return { foo: foo, bar: bar, moo: moo }; });

Luego, el resto de los módulos pueden usar este espacio de nombres durante la definición:

define([ "namespace" ], function (namespace) { namespace.foo(42); });

O en tiempo de ejecución, en algún otro módulo:

define(function () { return { initialize: function () { require([ "namespace" ], function (namespace) { namespace.foo(42); }); } }; });

En los usos anteriores, nada más que define y require son globales. Por supuesto, estos son solo ejemplos ilustrativos, ya que hay muchos tipos diferentes de definir / usar módulos en RequireJS.


Su módulo solo "filtra" su portador de espacio de nombres, por lo que es bastante aceptable.


[[Cuento]]

No haga variables globales nunca y use un cargador de módulos asíncronos como RequireJS o Curl

[[Larga historia]]

Ese comentario estaba mal estructurado.

No hay nada malo con el sistema de módulos. Me quejaba de usar variables globales. (Todavía creo que el patrón genérico completo del módulo está hinchado).

Si debe evitar todas las variables globales es una pregunta diferente y creo que es una cuestión de estilo. Puede usar un cargador asíncrono para pasar los módulos o usar la window para pasar los módulos.

  • ¿Qué se entiende por "filtración" en el ámbito global?

Lo que quise decir fue tu creación de variables globales. Minimizar el uso de variables globales es un patrón. En la programación de estilo funcional es posible tener cero variables globales, pero este es un patrón diferente al uso de módulos globales.

  • ¿Por qué es tan malo?

Tener un estado global puede causar que ese estado se corrompa.

  • ¿Cómo lo evitas?

Usted no puede Sin embargo, puede minimizar la cantidad de variables globales. Para evitar tener un estado global completo puede utilizar cargadores asíncronos. Estos definen algunas variables globales para ti que luego puedes usar.

  • Al querer crear objetos personalizados persistentes, ¿por qué es malo el patrón del módulo (abajo)?

No hay nada malo con el patrón del módulo. El problema es almacenar tu módulo globalmente. El problema es tener espacios de nombres globales.

  • Los patrones de diseño le permiten encapsular lógica compleja, ¿es la encapsulación repentinamente mala simplemente porque estamos escribiendo en JavaScript?

Ahora que he aclarado la intención del comentario, esta pregunta no es realmente relevante

  • O ... ¿este comentarista está simplemente equivocado?

El comentario fue mal redactado en el mejor de los casos. Me opuse a los espacios de nombres globales en lugar de a los módulos, pero no lo dije correctamente.

La alternativa es usar cargadores asíncronos y definir módulos. Estos pueden ser reducidos a dos variables globales. define y require .

require = function(moduleName, callback)

Esto obtendrá un módulo y luego se lo devolverá.

define = function(obj)

Esto define un módulo.

El concepto aquí es que usted codifica múltiples archivos de la siguiente manera:

// main.js require([ "foo.js", "bar.js", ..., ], function(foo, bar, ...) { // do stuff }); //foo.js (function() { var namespace = modulePatternCode; ... define(namespace): })(); //bar.js (function() { var namespace = modulePatternCode; ... define(namespace): })();