Pregunta

He escuchado de una variedad de lugares que las variables globales son intrínsecamente desagradables y malvadas, pero cuando hago algunos Javascript no orientados a objetos, no puedo ver cómo evitarlos. Digamos que tengo una función que genera un número usando un algoritmo complejo que usa números aleatorios y otras cosas, pero necesito seguir usando ese número en particular en alguna otra función que sea una devolución de llamada o algo así, por lo que no puede ser parte de la misma función.

Si el número generado originalmente es una variable local, no será accesible desde allí. Si las funciones fueran métodos de objeto, podría hacer que el número sea una propiedad, pero no lo son y parece un poco complicado modificar toda la estructura del programa para hacer esto. ¿Es realmente tan mala una variable global?

¿Fue útil?

Solución

Para hacer que una variable calculada en la función A sea visible en la función B, tiene tres opciones:

  • que sea global,
  • convertirlo en una propiedad de objeto, o
  • pásalo como parámetro cuando llames a B desde A.

Si su programa es bastante pequeño, entonces los globales no son tan malos. De lo contrario, consideraría usar el tercer método:

function A()
{
    var rand_num = calculate_random_number();
    B(rand_num);
}

function B(r)
{
    use_rand_num(r);
}

Otros consejos

Creo que lo mejor que puede hacer aquí es definir una variable de alcance global única y descargar sus variables allí:

var MyApp = {}; // Globally scoped object

function foo(){
    MyApp.color = 'green';
}

function bar(){
    alert(MyApp.color); // Alerts 'green'
} 

Nadie debería gritarte por hacer algo como lo anterior.

Considere usar espacios de nombres:

(function() {
    var local_var = 'foo';
    global_var = 'bar'; // this.global_var and window.global_var also work

    function local_function() {}
    global_function = function() {};
})();

Tanto local_function como global_function tienen acceso a todas las variables locales y globales.

Editar : Otro patrón común:

var ns = (function() {
    // local stuff
    function foo() {}
    function bar() {}
    function baz() {} // this one stays invisible

    // stuff visible in namespace object
    return {
        foo : foo,
        bar : bar
    };
})();

Ahora se puede acceder a las propiedades ed return mediante el objeto de espacio de nombres, p. ns.foo , sin perder el acceso a las definiciones locales.

Lo que estás buscando es técnicamente conocido como curry.

function getMyCallback(randomValue)
{
    return function(otherParam)
    {
        return randomValue * otherParam //or whatever it is you are doing.
    }

}

var myCallback = getMyCallBack(getRand())

alert(myCallBack(1));
alert(myCallBack(2));

Lo anterior no es exactamente una función currificada, pero logra el resultado de mantener un valor existente sin agregar variables al espacio de nombres global o requerir algún otro repositorio de objetos para él.

Si otra función necesita usar una variable, se la pasa a la función como argumento.

También las variables globales no son inherentemente desagradables y malvadas. Mientras se usen correctamente, no hay problema con ellos.

Si existe la posibilidad de que reutilice este código, entonces probablemente haría el esfuerzo de ir con una perspectiva orientada a objetos. Usar el espacio de nombres global puede ser peligroso: corre el riesgo de encontrar errores difíciles de encontrar debido a los nombres de variables que se reutilizan. Por lo general, empiezo usando un enfoque orientado a objetos para algo más que una simple devolución de llamada para que no tenga que volver a escribir. Siempre que tenga un grupo de funciones relacionadas en JavaScript, creo que es un candidato para un enfoque orientado a objetos.

Otro enfoque es el que recogí de una publicación del foro Douglas Crockford ( http : //bytes.com/topic/javascript/answers/512361-array-objects ). Aquí está ...

Douglas Crockford escribió:

15 de julio de 2006

" Si desea recuperar objetos por id, entonces debe usar un objeto, no un formación. Como las funciones también son objetos, puede almacenar los miembros en funcionar en sí mismo. "

function objFacility(id, name, adr, city, state, zip) {

    return objFacility[id] = {

        id: id,
        name: name,
        adr: adr,
        city: city,
        state: state,
        zip: zip

    }
}

objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);

" El objeto se puede obtener con "

objFacility.wlevine

Ahora se puede acceder a las propiedades de los objetos desde cualquier otra función.

Me pareció extremadamente útil en relación con la pregunta original:

Devuelva el valor que desea utilizar en functionOne, luego llame a functionOne dentro de functionTwo, luego coloque el resultado en una nueva var y haga referencia a esta nueva var dentro de functionTwo. Esto debería permitirle usar la var declarada en functionOne, dentro de functionTwo.

function functionOne() {
  var variableThree = 3;
  return variableThree;
}

function functionTwo() {
  var variableOne = 1;
  var var3 = functionOne();

  var result = var3 - variableOne;

  console.log(variableOne);
  console.log(var3);
  console.log('functional result: ' + result);
}

functionTwo();

No conozco los detalles específicos de su problema, pero si la función necesita el valor, entonces puede ser un parámetro pasado a través de la llamada.

Los globales se consideran malos porque el estado global y múltiples modificadores pueden crear códigos difíciles de seguir y errores extraños. Para muchos actores, jugar con algo puede crear caos.

Puede controlar completamente la ejecución de las funciones de JavaScript (y pasar variables entre ellas) utilizando eventos jQuery personalizados ... Me dijeron que esto no era posible en todos estos foros, pero conseguí que algo funcionara exactamente. (incluso usando una llamada ajax).

Aquí está la respuesta (IMPORTANTE: no es la respuesta marcada, sino la respuesta de mí "Emile"):

Cómo obtener una variable devuelta funciones múltiples: Javascript / jQuery

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top