paginas - variables en javascript ejemplos
He oído que las variables globales son malas, ¿qué solución alternativa debería usar? (9)
El estado global causa problemas en varias áreas. Uno es la reutilización del código. Cuando accede a un estado global, significa que el componente debe conocer su entorno (algo externo a él). Debe evitar esto tanto como sea posible, ya que hace que el componente sea impredecible.
Digamos que tengo un objeto que accede a su función globalVariables y quiero usarlo en otra página. ¿Cómo sé definir el objeto globalVariables o incluso cómo definirlo? Sin embargo, si puede pasar la información a un constructor o como argumento a una función, entonces puedo determinar fácilmente qué se requiere para el objeto.
Además, cuando accede o modifica el alcance global, corre el riesgo de afectar a otros objetos. Esta es la razón por la cual las bibliotecas como jquery usan solo un nombre en el alcance global (el menos posible). Disminuye la posibilidad de conflicto con otras bibliotecas. En otras palabras, el alcance global está fuera de tu control, por lo que es peligroso.
He leído por todas partes que las variables globales son malas y deben usarse alternativas. En Javascript específicamente, ¿qué solución debería elegir?
Estoy pensando en una función, que cuando alimenta dos argumentos ( function globalVariables(Variable,Value)
) busca si Variable existe en una matriz local y si establece su valor en Value
, de lo contrario, se añaden Variable
y Value
. Si se llama a la función sin argumentos ( function globalVariables()
) devuelve la matriz. Quizás si la función se dispara con un solo argumento ( function globalVariables(Variable)
) devuelve el valor de Variable
en la matriz.
¿Qué piensas? Me gustaría escuchar sus soluciones alternativas y argumentos para usar variables globales.
Cómo usará globalVariables();
function append(){
globalVariables("variable1","value1"); //globalVariables() would append variable1 to it''s local array.
};
function retrieve(){
var localVariable1 = globalVariables("variable1"); //globalVariables() would return "value1".
};
function retrieveAll(){
var localVariable1 = globalVariables(); //globalVariables() would return the globalVariable()''s entire, local [persistently stored between calls] array.
};
function set(){
globalVariables("variable1","value2"); //globalVariables() would set variable1 to "value2".
};
¿Es esto un Patrón Singleton por cierto?
En este escenario específico, una función puede establecer una variable en un punto en el tiempo, y mucho más tarde otra función, tal vez cuando un usuario envía un formulario, tendrá que obtener esa variable. Por lo tanto, la primera función no podía pasar la variable como un argumento a la función posterior ya que nunca se llamaría desde la primera.
Gracias, agradezco toda tu ayuda!
El problema con su solución es que solo hace que los códigos sean más difíciles de entender a la vez que se mantienen todas las desventajas de las variables globales. La página a la que vinculó cubre los problemas. El único problema que su solución propuesta realmente resuelve es la contaminación del espacio de nombres, pero a costa de no poder ver qué variables globales se declaran tan fácilmente como la declaración es una llamada a la función).
La solución es escribir código sin variables globales. Si una función necesita un valor, páselo como argumento.
El uso de variables globales generalmente es una mala práctica, independientemente del idioma de elección. Ni siquiera se les permite usar (fácilmente) cuando están en modo estricto , lo cual recomiendo encarecidamente.
Considera este pedazo de código que encontré:
if (typeof session != ''undefined'' && !data.cart.request_status)
data.input_definitions.passengers =
inflate_passenger(session, data.input_definitions.passengers);
Necesitaba dar la vuelta y preguntarle a un programador de dónde vino esta variable de session
, ya que no apareció ninguna búsqueda de código donde se configuró.
Resulté que otro paquete de la compañía establece la variable global. Código es como una broma: si necesita explicarlo, probablemente no sea tan bueno.
Solución con ES6:
Si está en Node, use import
o require
para llevar las cosas deseadas al alcance léxico, no permita que las personas toquen su entorno global sin que usted lo sepa.
import {Sesssion} from ''api-core'';
const Session = require(''api-core'').session;
Si está en el frontend entregando código para el navegador no puede usar la import
menos que transpile su código ES6 usando Babel .
Ejemplo de transpiling usando Gulp.js:
// $ npm install --save-dev gulp-babel babel-preset-es2015
// gulpfile.js
const gulp = require(''gulp'');
const babel = require(''gulp-babel'');
gulp.task(''transpile'', () => {
return gulp.src(''src/app.js'')
.pipe(babel({presets: [''es2015'']}))
.pipe(gulp.dest(''dist''));
});
// $ gulp transpile
Solución alternativa heredada:
Cuando se utilizan las características de ES6 no es una opción, la única solución para usar un conjunto de variables globales es usar solo una, y tener esperanza:
// scripts/app.js
var MyApp = {
globals: {
foo: "bar",
fizz: "buzz"
}
};
La razón principal por la que se desaconsejan las variables globales en javascript es porque, en JavaScript, todos los códigos comparten un solo espacio de nombres global, también javascript tiene variables globales implícitas, es decir. las variables que no se declaran explícitamente en el ámbito local se agregan automáticamente al espacio de nombres global. Confiar demasiado en las variables globales puede provocar colisiones entre varios guiones en la misma página (lea los artículos de Douglas Crockford ).
Una forma de reducir las variables globales es utilizar el patrón del módulo YUI . La idea básica es ajustar todo el código en una función que devuelve un objeto que contiene funciones a las que se debe acceder fuera de su módulo y asignarle el valor de retorno a una única variable global.
var FOO = (function() {
var my_var = 10; //shared variable available only inside your module
function bar() { // this function not available outside your module
alert(my_var); // this function can access my_var
}
return {
a_func: function() {
alert(my_var); // this function can access my_var
},
b_func: function() {
alert(my_var); // this function can also access my_var
}
};
})();
ahora para usar funciones en su módulo en otro lugar, use FOO.a_func()
. De esta forma, para resolver los conflictos globales del espacio de nombres, solo necesita cambiar el nombre de FOO
.
Las variables globales son malas ... si no se administran!
Los riesgos potenciales de las variables globales son tan altos como los beneficios de placer y productividad de tener objetos usados frecuentemente listos para usar.
No creo que uno deba buscar una sola alternativa. En su lugar, aboguen por un objeto a cargo de la gestión de esos elementos globales y, a medida que el código base / componente madure, refactorícelos.
Una cosa no mencionada en las respuestas actuales que creo que es crítica es la comprensión de los contenedores DI y IoC. Estos abordan muchos de los problemas que las personas intentan resolver con variables globales, pero que cubren preocupaciones relacionadas que los globales comunes no pueden, como los ciclos de vida de los objetos.
Otra respuesta más explica con función anónima como this menciona this artículo,
Las funciones anónimas son difíciles de depurar, mantener, probar o reutilizar.
Aquí hay un ejemplo con una función normal. Es más fácil de leer y entender
/* global variable example */
var a= 3, b= 6;
function fwithglobal(){
console.log(a, b); // 3 6 expected
}
fwithglobal(); // first call
function swithglobal(){
var a=9;
console.log(a, b); // not 3 6 but 9 6
}
swithglobal(); // second call
/* global variable alternative(function parameter) */
function altern(){
var a= 3, b= 6; // var keyword needed
f_func(a,b);
s_func(a,b);
}
function f_func(n, m){
console.log(n, m); // 3 6 expected
}
function s_func(n, m){
var a=9;
console.log(n, m); // 3 6 expected
}
altern(); // only once
Realmente no quieres hacer esto.
En cuanto a por qué, consulte, por ejemplo, la publicación principal aquí: ¿Cuál es el código MÁS EVIDENTE que ha visto en un entorno empresarial de producción?
Como nota al margen, siempre se puede ejecutar el código "global" sin ensuciar el lugar con globales:
(function () {
var notaglobal = 1;
alert(notaglobal);
})();
//notaglobal is not defined in this scope
Semántica, muchacho. Semántica.
Comience con un global: myApp = {}; Todo debería estar en eso. La única excepción sería su biblioteca AJAX (hay algunas excepciones extremas, como trabajar con devoluciones de llamada JSONP).
Deben existir muy pocas propiedades en myApp. Deberá mantener las propiedades de la aplicación en contenedores como configuración o configuración.
myApp = {
config:{
prop:1
},
settings:{
prop:2
},
widgets:{
List: function(props){},
Item: function(props){}
}
}
Entonces puede tener más propiedades en módulos inferiores, componentes, singletons y constructores de clase (widgets).
Esta configuración le brinda la ventaja adicional de poder acceder a cualquier propiedad desde cualquier otra ubicación, ya que puede obtenerla con myApp global. Sin embargo, debe usar "esto" siempre que sea posible porque la búsqueda es más rápida. Y simplemente establece la propiedad directamente, no te molestes con las cosas pseudo getter / setter. Si realmente necesita un getter / setter, codifíquelo para ese uso específico.
La razón por la cual su ejemplo no funciona es que es demasiado genérico y parece que busca una excusa para trabajar en el espacio global.
Y no seas inteligente con las variables privadas. También son malos: http://clubajax.org/javascript-private-variables-are-evil/
var ASHIVA_HandsOffNHS = (function() {
// VARIABLES
var my_var = 10;
// PRIVATE FUNCTIONS
function bar() {
window.alert(my_var + 5);
}
// PUBLIC OBJECT
myObject = {};
myObject[''a_func''] = function() {
my_var += 10;
window.alert(my_var);
};
myObject[''b_func''] = function() {
my_var = 0;
window.alert(my_var);
};
return myObject;
})();
ASHIVA_HandsOffNHS.a_func();
ASHIVA_HandsOffNHS.b_func();
ASHIVA_HandsOffNHS.a_func();