Definir variável global em uma função JavaScript

511

É possível definir uma variável global em uma função JavaScript?

Eu quero usar a trailimagevariável (declarada na makeObjfunção) em outras funções.

<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
fonte
19
para declarar um simplesmente não usar o "var" palavra-chave global
Ibu
20
@ Ibrahim: "declarar um global simplesmente não use a palavra-chave" var "" Gak! O horror ! ;-) Felizmente, o modo estrito acaba com os globais implícitos.
TJ Crowder
28
@Ibrahim Diallo - não usar varnão declara uma variável global. Uma conseqüência da atribuição de um valor a uma variável não declarada é a criação de uma propriedade no objeto global, que é bem diferente de declarar uma variável.
RobG
1
informações úteis nesta resposta, também stackoverflow.com/a/4862268/1356098 :)
Erenor Paz

Respostas:

739

Sim, como os outros disseram, você pode usar varno escopo global (fora de todas as funções) para declarar uma variável global:

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

Como alternativa, você pode atribuir a uma propriedade em window:

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

... porque nos navegadores, todas as variáveis globais variáveis ​​globais declaradas com varsão propriedades do windowobjeto. (Na última especificação, ECMAScript 2015, o novo let, const, e classdeclarações no escopo global criar globals que não são propriedades do objeto global; um novo conceito em ES2015.)

(Há também o horror de globais implícitos , mas não faça isso de propósito e faça o possível para evitar fazê-lo por acidente, talvez usando os ES5s "use strict".)

Tudo isso dito: eu evitaria variáveis ​​globais se você puder (e você quase certamente pode). Como eu mencionei, eles acabam sendo propriedades de window, e windowjá estão bastante cheios, com todos os elementos com um id(e muitos com apenas um name) sendo despejados (e independentemente da especificação futura, o IE despeja praticamente qualquer coisa com um namelá) )

Em vez disso, envolva seu código em uma função de escopo e use variáveis ​​locais para essa função de escopo, e faça com que suas outras funções sejam fechadas nela:

<script>
(function() { // Begin scoping function
    var yourGlobalVariable; // Global to your code, invisible outside the scoping function
    function foo() {
        // ...
    }
})();         // End scoping function
</script>
TJ Crowder
fonte
98
+1 Declarar explicitamente a janela é a maneira mais legível.
Caspar Kleijne
8
Observe que o uso windownão funcionará no Node. O truque mais fácil aqui é definir: GLOBAL.window = GLOBAL;- conforme explicado nesta pergunta relacionada . Claro, não é bonito conceitualmente. Eu prefiro fazer as coisas ao contrário, para que eu possa usar em GLOBALvez de window.
Domi
4
@CasparKleijne, eu não entendo. Por que você o atribuiria na janela quando você literalmente não tem evidências de que o objeto da janela realmente exista. Você não sabe nada sobre como seu código será usado no futuro. Pode até ser usado no ambiente MongoDB ou rino em vez do seu nó. E o objeto da janela também não é visível, mesmo no navegador, se você usar web workers, por exemplo. Isso eliminará completamente a reutilização.
Gherman
4
window.yourGlobalVariable = ...;funciona como um encanto depois de ler 5 a 6 perguntas no site da pilha.
Ahmed Syed
6
@ JacquesKoekemoer: Não há nenhuma razão para usar evallá. Em vez disso:window[dynamic_variable_name] = dynamic_variable_value;
TJ Crowder
19

ATUALIZAÇÃO1: Se você ler os comentários, haverá uma boa discussão sobre esta convenção de nomenclatura específica.

ATUALIZAÇÃO2: Parece que desde que minha resposta foi publicada, a convenção de nomes ficou mais formal. As pessoas que ensinam, escrevem livros etc. falam sobre vardeclaração e functiondeclaração.

ATUALIZAÇÃO3: Aqui está o post adicional da wikipedia que suporta meu argumento: http://en.wikipedia.org/wiki/Declaration_(computer_programming)#Declarations_and_Definitions

... e para responder à pergunta principal. DECLARE antes da sua função. Isso funcionará e seguirá as boas práticas de declarar suas variáveis ​​no topo do escopo :)

op1ekun
fonte
7
Se você deseja definir suas variáveis ​​em outro lugar, não deixe de entender o que é a elevação. Aqui está um artigo muito bom sobre isso de forma adequadagood.com/2010/2/JavaScript-Scoping-and-Hoisting . Boa sorte!
op1ekun
1
Isso não é o que significa definitione declarationsignifica em C. Sua primeira linha pode ser uma declaração ou uma definição (dependendo de onde estiver); o segundo é apenas uma tarefa. Uma declaração apenas especifica a interpretação do identificador (ou seja, myVaré um int); se a declaração também reserva armazenamento, é a definition. Isso não está relacionado à digitação; é parte de como as unidades de compilação entendem referências a outras unidades de compilação.
EML
4
Mesmo em JS, var myVaré chamado de declaração (não precisa ser digitado) e myVar = 10uma atribuição . Eu ouvi o termo "definição" para o composto ( var myVar = 10;).
Bergi
2
Isso não ajuda a responder à pergunta. Deveria ter sido um comentário, não uma resposta.
Stuntddude
2
@ Stuntddude você provavelmente está certo :( Comecei a responder à pergunta e, em seguida, decidi divergir um pouco, e é isso que temos. Ainda algumas pessoas ainda acham útil, então deixei aqui. # 1
op1ekun # 03
15

Apenas declare

var trialImage;

lado de fora. Então

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

Espero que isto ajude.

harihb
fonte
12

Não, você não pode. Apenas declare a variável fora da função. Você não precisa declarar isso ao mesmo tempo em que atribui o valor:

var trailimage;

function makeObj(address) {
  trailimage = [address, 50, 50];
Guffa
fonte
1
Desculpa! "É possível definir uma variável global em uma função JavaScript?" - "Não, você não pode" não está correto, como mostra a primeira resposta!
mustafa.0x
5
@ mustafa.0x: Você está enganado. Você não pode definir uma variável global dentro de uma função. Você pode criar implicitamente uma variável global ou criar uma propriedade de janela dentro de uma função, mas não pode definir uma variável global dentro de uma função.
Guffa
1
Com relação ao JavaScript em um ambiente de navegador, uma variável global e uma propriedade de windowsão sinônimos. De qualquer maneira, a distinção semântica que você está fazendo é clara, então não me importo de não fazer voto negativo. Edit: incapaz de alterar meu voto, desculpe!
mustafa.0x
2
se você não está usando strict (mas por que não está usando strict?), pode realmente declarar e definir vars globais dentro de uma função , indo contra todas as boas práticas e simplesmente não usando o var, que é o que Guffa quis dizer com criar implicitamente (como @DhruvPathak também apontou).
Cregox # 25/17
11

Apenas declare-o fora das funções e atribua valores dentro das funções. 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

Ou simplesmente remover "var" do nome da variável dentro da função também a torna global, mas é melhor declará-la fora uma vez para obter um código mais limpo. Isso também 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 exemplo explique mais: 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
fonte
3

É muito simples definir a variável trailimage fora da função e definir seu valor na função makeObj. Agora você pode acessar seu valor de qualquer lugar.

var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;
var trailimage;
function makeObj(address) {
      trailimage = [address, 50, 50];
      ....
}
Bharath
fonte
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;

Percebo que provavelmente há muitos erros de sintaxe nisso, mas é a idéia geral ... Muito obrigado LayZee por apontar isso ... Você pode encontrar o que é um armazenamento local e de sessão em http: //www.w3schools. com / html / html5_webstorage.asp . Eu precisava da mesma coisa para o meu código e essa foi uma ótima ideia.

ShanerM13
fonte
Até o momento, essa é a única resposta que funciona, mas requer recarregar a página e location.reload(false);atualizá-la repetidamente.
iyrin
1

Exemplo clássico:

window.foo = 'bar';

Exemplo moderno e seguro, seguindo as melhores práticas usando um IIFE :

;(function (root) {
    'use strict'

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

Atualmente, também há a opção de usar a API WebStorage

localStorage.foo = 42;

ou

sessionStorage.bar = 21;

Em termos de desempenho, não tenho certeza se é visivelmente mais lento que o armazenamento de valores em variáveis.

Suporte amplo ao navegador, conforme indicado em Posso usar ...

Lars Gyrup Brink Nielsen
fonte
localStorage e sessionStorage funciona apenas para valores de sequência.
precisa saber é o seguinte
Isso mesmo, @HereToLearn_, mas você pode usar localStorage.foo = JSON.stringify({ arbitrary: 'object', meaning: 42, awesome: true });e var foo = JSON.decode(localStorage.foo);.
Lars Gyrup Brink Nielsen 26/10/2015
O que localStoragetem a ver com variáveis ​​globais?
Michał Perłakowski
1
O OP está procurando a solução para este problema: "Quero usar a variável trailimage (declarada na função makeObj) em outras funções." Quem disse que a solução precisa envolver variáveis ​​globais? Variáveis ​​globais raramente são uma boa solução para qualquer coisa.
Lars Gyrup Brink Nielsen
0

Então você quer a variável dentro da função disponível fora da função? Por que não retornar os resultados da variável dentro da função? var x = function returnX { var x = 0; return x; }é a ideia ...

    <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>

Não testei isso, mas se seu código funcionou antes dessa pequena alteração, ele deve funcionar.

ShanerM13
fonte
-1

Aqui está um código de exemplo que pode 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 

Aqui encontrei uma boa resposta Como posso declarar uma variável global em JavaScript

Shohanur Rahaman
fonte
Embora isso possa teoricamente responder à pergunta, seria preferível incluir aqui as partes essenciais da resposta e fornecer o link para referência.
Rohit Gupta
-1

Aqui está outro método fácil para disponibilizar a variável em outras funções sem precisar usar variáveis ​​globais:

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

makeObj();
someOtherFunction();

am2124429
fonte
-2

se você estiver criando uma função de inicialização, poderá definir funções e variáveis ​​globais da seguinte maneira:

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

Como a função é invocada globalmente com esse argumento, esse é o escopo global aqui. Então, o algo deve ser uma coisa global.

Konstantin Isaev
fonte
thisestá undefinedno modo estrito fora de uma função e não deve ser usado para se referir ao objeto global.
Michał Perłakowski 16/01