Definir variable global en una función de JavaScript

511

¿Es posible definir una variable global en una función de JavaScript?

Quiero usar la trailimagevariable (declarada en la makeObjfunción) en otras funciones.

<html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title></title>
        <script type="text/javascript">
            var offsetfrommouse = [10, -20];
            var displayduration = 0;
            var obj_selected = 0;
            function makeObj(address) {
                **var trailimage = [address, 50, 50];**
                document.write('<img id="trailimageid" src="' + trailimage[0] + '" border="0"  style=" position: absolute; visibility:visible; left: 0px; top: 0px; width: ' + trailimage[1] + 'px; height: ' + trailimage[2] + 'px">');
                obj_selected = 1;
            }

            function truebody() {
                return (!window.opera && document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body;
            }
            function hidetrail() {
                var x = document.getElementById("trailimageid").style;
                x.visibility = "hidden";
                document.onmousemove = "";
            }
            function followmouse(e) {
                var xcoord = offsetfrommouse[0];
                var ycoord = offsetfrommouse[1];
                var x = document.getElementById("trailimageid").style;
                if (typeof e != "undefined") {
                    xcoord += e.pageX;
                    ycoord += e.pageY;
                }
                else if (typeof window.event != "undefined") {
                    xcoord += truebody().scrollLeft + event.clientX;
                    ycoord += truebody().scrollTop + event.clientY;
                }
                var docwidth = 1395;
                var docheight = 676;
                if (xcoord + trailimage[1] + 3 > docwidth || ycoord + trailimage[2] > docheight) {
                    x.display = "none";
                    alert("inja");
                }
                else
                    x.display = "";
                x.left = xcoord + "px";
                x.top = ycoord + "px";
            }

            if (obj_selected = 1) {
                alert("obj_selected = true");
                document.onmousemove = followmouse;
                if (displayduration > 0)
                    setTimeout("hidetrail()", displayduration * 1000);
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <img alt="" id="house" src="Pictures/sides/right.gif" style="z-index: 1; left: 372px;
            top: 219px; position: absolute; height: 138px; width: 120px" onclick="javascript:makeObj('Pictures/sides/sides-not-clicked.gif');" />
        </form>
    </body>
</html>
Hamze
fuente
19
a declarar el mundial simplemente no utilizar el "var" palabra clave
Ibu
20
@Ibrahim: "para declarar un global simplemente no use la palabra clave" var "" Gak! El horror ! ;-) Afortunadamente, el modo estricto elimina los globales implícitos.
TJ Crowder
28
@Ibrahim Diallo: no usar varno declara una variable global. Una consecuencia de asignar un valor a una variable no declarada es la creación de una propiedad en el objeto global, que es muy diferente a declarar una variable.
RobG
1
información útil en esta respuesta, también stackoverflow.com/a/4862268/1356098 :)
Erenor Paz

Respuestas:

739

Sí, como han dicho los demás, puede usarlo vara nivel global (fuera de todas las funciones) para declarar una variable global:

<script>
var yourGlobalVariable;
function foo() {
    // ...
}
</script>

Alternativamente, puede asignar a una propiedad en window:

<script>
function foo() {
    window.yourGlobalVariable = ...;
}
</script>

... porque en los navegadores, todas las variables globales variables globales declaradas con varson propiedades del windowobjeto. (En la última especificación, ECMAScript 2015, el nuevo let, consty classdeclaraciones en el ámbito global crear variables globales que no son propiedades del objeto global, un nuevo concepto en ES2015).

(También existe el horror de los globales implícitos , pero no lo haga a propósito y haga todo lo posible para evitar hacerlo por accidente, tal vez utilizando ES5 "use strict").

Todo lo dicho: evitaría las variables globales si es posible (y casi seguro que puede). Como mencioné, terminan siendo propiedades de window, y windowya está lo suficientemente lleno de gente con todos los elementos con un id(y muchos con solo un name) que se vierten en él (e independientemente de la próxima especificación, IE descarta casi cualquier cosa con un contenido nameallí) )

En cambio, envuelva su código en una función de alcance y use variables locales para esa función de alcance, y haga que sus otras funciones se cierren dentro de ella:

<script>
(function() { // Begin scoping function
    var yourGlobalVariable; // Global to your code, invisible outside the scoping function
    function foo() {
        // ...
    }
})();         // End scoping function
</script>
TJ Crowder
fuente
98
+1 Declararlo explícitamente en la ventana es la forma más fácil de leer.
Caspar Kleijne
99
Tenga en cuenta que el uso windowno funcionará en Node. El truco más fácil aquí es establecer: GLOBAL.window = GLOBAL;- como se explica en esta pregunta relacionada . Por supuesto, no es bastante conceptual. Prefiero hacer las cosas al revés, por lo que puedo usar en GLOBALlugar de window.
Domi
44
@CasparKleijne, no lo entiendo. ¿Por qué lo asignarías en una ventana cuando literalmente no tienes evidencia de que el objeto de la ventana realmente existe? No sabe nada acerca de cómo se usará su código en el futuro. Incluso podría usarse en el entorno MongoDB o rino en lugar de su nodo. Y el objeto de la ventana tampoco es visible incluso en el navegador si utiliza trabajadores web, por ejemplo. Esto matará por completo la reutilización.
Gherman
44
window.yourGlobalVariable = ...;funciona de maravilla después de leer 5 a 6 preguntas en el sitio de pila.
Ahmed Syed
66
@JacquesKoekemoer: No hay ninguna razón para usar evalallí. En cambio:window[dynamic_variable_name] = dynamic_variable_value;
TJ Crowder
19

ACTUALIZACIÓN1: si lee los comentarios, hay una buena discusión sobre esta convención de nomenclatura en particular.

ACTUALIZACIÓN2: Parece que desde que se publicó mi respuesta, la convención de nombres se ha vuelto más formal. Las personas que enseñan, escriben libros, etc. hablan de vardeclaración y functiondeclaración.

ACTUALIZACIÓN3: Aquí está la publicación adicional de Wikipedia que respalda mi punto: http://en.wikipedia.org/wiki/Declaration_(computer_programming)#Declarations_and_Definitions

... y para responder a la pregunta principal. DECLARE la variable antes de su función. Esto funcionará y cumplirá con la buena práctica de declarar sus variables en la parte superior del alcance :)

op1ekun
fuente
77
Si desea definir sus variables en otro lugar, asegúrese de comprender qué es la elevación. Aquí hay un artículo muy bueno al respecto adecuadamentegood.com/2010/2/JavaScript-Scoping-and-Hoisting . ¡Buena suerte!
op1ekun
1
Esto no es lo que definitiony declarationmedia en C. Su primera línea podría ser una declaración o una definición (dependiendo de donde está); el segundo es solo una tarea. Una declaración solo especifica la interpretación del identificador (es decir, myVares un int); si la declaración también reserva almacenamiento, es a definition. Esto no está relacionado con la escritura; Es parte de cómo las unidades de compilación entienden las referencias a otras unidades de compilación.
EML
44
Incluso en JS, var myVarse llama declaración (no es necesario escribirla) y myVar = 10una asignación . He escuchado el término "definición" para el compuesto ( var myVar = 10;).
Bergi
2
Esto no ayuda a responder la pregunta. Debería haber sido un comentario, no una respuesta.
Stuntddude
2
@Stuntddude probablemente tengas razón :( Comencé a responder la pregunta y luego decidí divergir un poco, y bueno, esto es lo que tenemos. Todavía algunas personas todavía lo encuentran útil, así que lo dejé aquí. Gracias por tu comentarios!
op1ekun
15

Solo declara

var trialImage;

fuera de. Entonces

function makeObj(address) {
    trialImage = [address, 50, 50];
..
..
}

Espero que esto ayude.

harihb
fuente
12

No puedes. Simplemente declare la variable fuera de la función. No tiene que declararlo al mismo tiempo que asigna el valor:

var trailimage;

function makeObj(address) {
  trailimage = [address, 50, 50];
Guffa
fuente
1
¡Lo siento! "¿Es posible definir una variable global en una función de JavaScript?" - "No, no puedes" no es correcto, como muestra la primera respuesta.
mustafa.0x
55
@ mustafa.0x: Estás equivocado. No puede definir una variable global dentro de una función. Puede crear implícitamente una variable global o crear una propiedad de ventana dentro de una función, pero no puede definir una variable global dentro de una función.
Guffa
1
Con respecto a JavaScript en un entorno de navegador, una variable global y una propiedad de windowson sinónimos. De cualquier manera, la distinción semántica que está haciendo es clara, por lo que no me importa dejar de votar. Editar: no se puede cambiar mi voto, lo siento.
mustafa.0x
2
si no está usando estricto (pero ¿por qué no está usando estricto?), en realidad puede declarar y definir variables globales dentro de una función yendo en contra de todas las buenas prácticas y simplemente no usando el var, que es lo que Guffa quiso decir implícitamente crear (como @DhruvPathak también señaló allí).
cregox
11

Simplemente declare fuera de las funciones y asigne valores dentro de las funciones. Algo como:

<script type="text/javascript">
    var offsetfrommouse = [10, -20];
    var displayduration = 0;
    var obj_selected = 0;
    var trailimage = null ;  // GLOBAL VARIABLE
    function makeObj(address) {
        trailimage = [address, 50, 50];  //ASSIGN VALUE

O simplemente eliminar "var" de la función interna de su nombre de variable también lo hace global, pero es mejor declararlo afuera una vez para obtener un código más limpio. Esto también funcionará:

var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;

function makeObj(address) {
    trailimage = [address, 50, 50];  //GLOBAL VARIABLE , ASSIGN VALUE

Espero que este ejemplo explique más: http://jsfiddle.net/qCrGE/

var globalOne = 3;
testOne();

function testOne()
{
    globalOne += 2;
    alert("globalOne is : " + globalOne );
    globalOne += 1;
}

alert("outside globalOne is : " + globalOne);

testTwo();

function testTwo()
{
    globalTwo = 20;
    alert("globalTwo is " + globalTwo);
    globalTwo += 5;
}

alert("outside globalTwo is :" + globalTwo);
DhruvPathak
fuente
3

Es muy simple definir la variable trailimage fuera de la función y establecer su valor en la función makeObj. Ahora puede acceder a su valor desde cualquier lugar.

var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;
var trailimage;
function makeObj(address) {
      trailimage = [address, 50, 50];
      ....
}
Bharat
fuente
2
    var Global = 'Global';

    function LocalToGlobalVariable() {

    //This creates a local variable.

    var Local = '5';

    //Doing this makes the variable available for one session
    //(a page refresh - Its the session not local)

    sessionStorage.LocalToGlobalVar = Local;

    // It can be named anything as long as the sessionStorage references the local variable.
    // Otherwise it won't work
    //This refreshes the page to make the variable take effect instead of the last variable set.

    location.reload(false);
    };

    //This calls the variable outside of the function for whatever use you want.

    sessionStorage.LocalToGlobalVar;

Me doy cuenta de que probablemente hay muchos errores de sintaxis en esto, pero es la idea general ... Muchas gracias LayZee por señalar esto ... Puede encontrar lo que es un almacenamiento local y de sesión en http: //www.w3schools. com / html / html5_webstorage.asp . He necesitado lo mismo para mi código y esta fue una muy buena idea.

ShanerM13
fuente
Hasta ahora, esta es la única respuesta que funciona, pero requiere volver a cargar la página y location.reload(false);actualizarla repetidamente.
iyrin
1

Ejemplo clásico:

window.foo = 'bar';

Ejemplo moderno y seguro siguiendo las mejores prácticas utilizando un IIFE :

;(function (root) {
    'use strict'

    root.foo = 'bar';
)(this));

Hoy en día, también existe la opción de usar la API de WebStorage

localStorage.foo = 42;

o

sessionStorage.bar = 21;

En cuanto al rendimiento, no estoy seguro de si es notablemente más lento que almacenar valores en variables.

Soporte generalizado del navegador como se indica en ¿Puedo usar ...

Lars Gyrup Brink Nielsen
fuente
localStorage y sessionStorage solo funciona para valores de cadena.
HereToLearn_
Eso es correcto, @HereToLearn_, pero luego puedes usar localStorage.foo = JSON.stringify({ arbitrary: 'object', meaning: 42, awesome: true });y var foo = JSON.decode(localStorage.foo);.
Lars Gyrup Brink Nielsen
¿Qué localStoragetiene que ver con las variables globales?
Michał Perłakowski
1
OP está buscando una solución a este problema: "Quiero usar la variable trailimage (declarada en la función makeObj) en otras funciones". ¿Quién dice que la solución tiene que involucrar variables globales? Las variables globales rara vez son una buena solución para algo.
Lars Gyrup Brink Nielsen
0

Entonces, ¿desea que la variable dentro de la función esté disponible fuera de la función? ¿Por qué no devolver los resultados de la variable dentro de la función? var x = function returnX { var x = 0; return x; }es la idea ...

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
    <title></title>
    <script type="text/javascript">

        var offsetfrommouse = [10, -20];
        var displayduration = 0;
        var obj_selected = 0;

        function makeObj(address) {
            var trailimage = [address, 50, 50];
            document.write('<img id="trailimageid" src="' + trailimage[0] + '" border="0"  style=" position: absolute; visibility:visible; left: 0px; top: 0px; width: ' + trailimage[1] + 'px; height: ' + trailimage[2] + 'px">');
            obj_selected = 1;
            return trailimage;
        }

        function truebody() {
            return (!window.opera && document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body;
        }

        function hidetrail() {
            var x = document.getElementById("trailimageid").style;
            x.visibility = "hidden";
            document.onmousemove = "";
        }

        function followmouse(e) {
            var xcoord = offsetfrommouse[0];
            var ycoord = offsetfrommouse[1];
            var x = document.getElementById("trailimageid").style;
            if (typeof e != "undefined") {
                xcoord += e.pageX;
                ycoord += e.pageY;
            }

            else if (typeof window.event != "undefined") {
                xcoord += truebody().scrollLeft + event.clientX;
                ycoord += truebody().scrollTop + event.clientY;
            }
            var docwidth = 1395;
            var docheight = 676;
            if (xcoord + trailimage[1] + 3 > docwidth || ycoord + trailimage[2] > docheight) {
                x.display = "none";
                alert("inja");
            }
            else
                x.display = "";
            x.left = xcoord + "px";
            x.top = ycoord + "px";
        }

        if (obj_selected = 1) {
            alert("obj_selected = true");
            document.onmousemove = followmouse;
            if (displayduration > 0)
                setTimeout("hidetrail()", displayduration * 1000);
        }

    </script>
</head>
<body>
    <form id="form1" runat="server">
    <img alt="" id="house" src="Pictures/sides/right.gif" style="z-index: 1; left: 372px; top: 219px; position: absolute; height: 138px; width: 120px" onclick="javascript:makeObj('Pictures/sides/sides-not-clicked.gif');" />
    </form>
</body>
</html>

No he probado esto, pero si su código funcionó antes de ese pequeño cambio, entonces debería funcionar.

ShanerM13
fuente
-1

Aquí hay un código de muestra que puede ser útil.

  var Human = function(){
   name = "Shohanur Rahaman";  // global variable
   this.name = "Tuly"; // constructor variable 
   var age = 21;
 };

  var shohan = new Human();

 document.write(shohan.name+"<br>");
 document.write(name);
 document.write(age); // undefined cause its local variable 

Aquí encontré una buena respuesta How-can-one-declare-a-global-variable-in-JavaScript

Shohanur Rahaman
fuente
Si bien esto puede responder teóricamente la pregunta, sería preferible incluir aquí las partes esenciales de la respuesta y proporcionar el enlace para referencia.
Rohit Gupta
-1

Aquí hay otro método fácil para hacer que la variable esté disponible en otras funciones sin tener que usar variables globales:

function makeObj() {
  // var trailimage = 'test';
  makeObj.trailimage = 'test';
}
function someOtherFunction() {
  document.write(makeObj.trailimage);
}

makeObj();
someOtherFunction();

am2124429
fuente
-2

Si está realizando una función de inicio, puede definir funciones y variables globales de la siguiente manera:

function(globalScope)
{
     //define something
     globalScope.something() { 
         alert("It works");
     };
}(window)

Debido a que la función se invoca globalmente con este argumento, este es el alcance global aquí. Entonces, el algo debería ser algo global.

Konstantin Isaev
fuente
thisestá undefineden modo estricto fuera de una función y no debe usarse para referirse al objeto global.
Michał Perłakowski