Определите глобальную переменную в функции JavaScript

511

Можно ли определить глобальную переменную в функции JavaScript?

Я хочу использовать trailimageпеременную (объявленную в makeObjфункции) в других функциях.

<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>
Хамзе
источник
19
для объявления глобального просто не используйте ключевое слово "var"
Ibu
20
@Ibrahim: «чтобы объявить глобальный, просто не используйте ключевое слово« var » Gak! Ужас ! ;-) К ​​счастью, строгий режим устраняет неявные глобальные переменные.
TJ Crowder
28
@Ibrahim Diallo - неиспользование varне объявляет глобальную переменную. Следствием присвоения значения необъявленной переменной является создание свойства в глобальном объекте, которое сильно отличается от объявления переменной.
RobG
1
полезная информация в этом ответе тоже stackoverflow.com/a/4862268/1356098 :)
Erenor Paz

Ответы:

739

Да, как уже говорили другие, вы можете использовать varв глобальной области видимости (вне всех функций) для объявления глобальной переменной:

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

Кроме того, вы можете назначить свойство на window:

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

... потому что в браузерах все глобальные переменные, объявленные с помощью глобальных переменных, varявляются свойствами windowобъекта. (В последней спецификации ECMAScript 2015, новый let, constи classзаявление в глобальном масштабе создать глобал, которые не являются свойством глобального объекта, новая концепцию в ES2015.)

(Существует также ужас неявных глобальных переменных , но не делайте это нарочно и делайте все возможное, чтобы избежать этого случайно, возможно, с помощью ES5 "use strict".)

Все это говорит: я бы избежал глобальных переменных, если вы можете (и вы почти наверняка можете). Как я уже говорил, они в конечном итоге являются свойствами window, и windowуже достаточно многолюдны, что со всеми элементами сid(и многими с просто aname), сбрасываемыми в него (и независимо от этой будущей спецификации, IE сбрасывает практически все, что находитсяnameтам). ).

Вместо этого, оберните ваш код в функцию области видимости и используйте переменные, локальные для этой функции области видимости, и сделайте ваши другие функции замыканиями внутри нее:

<script>
(function() { // Begin scoping function
    var yourGlobalVariable; // Global to your code, invisible outside the scoping function
    function foo() {
        // ...
    }
})();         // End scoping function
</script>
TJ Crowder
источник
98
+1 Явное объявление его окну - самый читаемый способ.
Каспар Кляйне
9
Обратите внимание, что использование windowне будет работать в Node. Самый простой трюк здесь - установить: GLOBAL.window = GLOBAL;- как объяснено в этом связанном вопросе . Конечно, это не очень концептуально. Я предпочитаю делать вещи наоборот, поэтому я могу использовать GLOBALвместо window.
Доми
4
@CasparKleijne, я этого не понимаю. Зачем вам присваивать его окну, если у вас буквально нет доказательств того, что объект окна действительно существует. Вы ничего не знаете о том, как ваш код будет использоваться в будущем. Он может даже использоваться в среде MongoDB или Rino вместо вашего узла. И объект окна также не виден даже в браузере, если вы используете, например, веб-работников. Это полностью убьет возможность повторного использования.
Герман
4
window.yourGlobalVariable = ...;работает как очарование после прочтения 5-6 вопросов на сайте стека.
Ахмед Сайед
6
@JacquesKoekemoer: Там нет никаких причин, чтобы использовать evalтам. Вместо этого:window[dynamic_variable_name] = dynamic_variable_value;
TJ Crowder
19

ОБНОВЛЕНИЕ 1: Если вы читаете комментарии, есть хорошая дискуссия вокруг этого конкретного соглашения об именах.

ОБНОВЛЕНИЕ 2: Кажется, что с тех пор, как мой ответ был опубликован, соглашение об именах стало более формальным. Люди, которые учат, пишут книги и т. Д. Говорят о varдекларации, иfunction декларации.

ОБНОВЛЕНИЕ 3: Вот дополнительный пост Википедии, который поддерживает мою точку зрения: http://en.wikipedia.org/wiki/Declaration_(computer_programming)#Declarations_and_Definitions

... и ответить на главный вопрос. ОБЪЯВЛЯЙТЕ переменную перед вашей функцией. Это будет работать, и это будет соответствовать хорошей практике объявления ваших переменных в верхней части области видимости :)

op1ekun
источник
7
Если вы хотите определить свои переменные в другом месте, обязательно поймите, что такое подъем. Вот очень хорошая статья об этом соответственноgood.com/ 2010/2/JavaScript-Scoping-and- Hoisting . Удачи!
op1ekun
1
Это не то, что definitionи declarationозначает в C. Ваша первая строка может быть либо объявлением, либо определением (в зависимости от того, где оно находится); второе - просто задание. Объявление просто определяет интерпретацию идентификатора (то есть. myVarЯвляется int); если декларация также резервирует хранилище, это definition. Это не связано с набором текста; это часть того, как единицы компиляции понимают ссылки на другие единицы компиляции.
EML
4
Даже в JS, var myVarназывается декларацией (она не должна быть набрана) и назначение . Я слышал термин "определение" для соединения ( ). myVar = 10var myVar = 10;
Берги
2
Это не поможет ответить на вопрос. Это должен был быть комментарий, а не ответ.
Stuntddude
2
@Stuntddude вы, вероятно, правы :( Я начал отвечать на вопрос, а затем решил немного расходиться, и это то, что у нас есть. Тем не менее, некоторые люди по-прежнему считают его полезным, поэтому я оставил его здесь. Спасибо за ваше обратная связь!
op1ekun
15

Просто объявить

var trialImage;

снаружи. затем

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

Надеюсь это поможет.

harihb
источник
12

Нет, ты не можешь. Просто объявите переменную вне функции. Вам не нужно объявлять его одновременно с назначением значения:

var trailimage;

function makeObj(address) {
  trailimage = [address, 50, 50];
Guffa
источник
1
Сожалею! «Можно ли определить глобальную переменную в функции JavaScript?» - «Нет, ты не можешь» не правильно, как показывает первый ответ!
mustafa.0x
5
@ mustafa.0x: Вы ошибаетесь. Вы не можете определить глобальную переменную внутри функции. Вы можете неявно создать глобальную переменную или свойство окна внутри функции, но вы не можете определить глобальную переменную внутри функции.
Гуффа
1
Что касается JavaScript в среде браузера, глобальная переменная и свойство windowявляются синонимами. В любом случае, семантическое различие, которое вы проводите, очевидно, поэтому я не возражаю против отказа от голосования. Изменить: не могу изменить свой голос, извините!
mustafa.0x
2
если вы не используете строгий (но почему вы не используете строгий?), вы на самом деле можете объявлять и определять глобальные переменные внутри функции , идя против всех хороших практик и просто не используя var, что Guffa подразумевал под неявным созданием (например, там указывал @DhruvPathak).
Cregox
11

Просто объявите это вне функций и присвойте значения внутри функций. Что-то вроде:

<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

Или простое удаление «var» из имени вашей переменной внутри функции также делает его глобальным, но лучше объявить его снаружи один раз для более чистого кода. Это также будет работать:

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

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

Я надеюсь, что этот пример объясняет больше: 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
источник
3

Очень просто определить переменную trailimage вне функции и установить ее значение в функции makeObj. Теперь вы можете получить доступ к его стоимости из любого места.

var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;
var trailimage;
function makeObj(address) {
      trailimage = [address, 50, 50];
      ....
}
Бхарат
источник
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;

Я понимаю, что в этом, вероятно, много синтаксических ошибок, но это общая идея ... Большое спасибо LayZee за то, что указал на это ... Вы можете найти локальное и сессионное хранилище на http: //www.w3schools. com / html / html5_webstorage.asp . Мне нужно то же самое для моего кода, и это была действительно хорошая идея.

ShanerM13
источник
Пока это единственный ответ, который работает вообще, но требует перезагрузки страницы и location.reload(false);многократного обновления страницы.
Айрин
1

Классический пример:

window.foo = 'bar';

Современный, безопасный пример, основанный на передовом опыте использования IIFE :

;(function (root) {
    'use strict'

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

В настоящее время есть также возможность использования API WebStorage

localStorage.foo = 42;

или

sessionStorage.bar = 21;

Производительность, я не уверен, что это заметно медленнее, чем сохранение значений в переменных.

Широкая поддержка браузеров, как указано на Могу ли я использовать ...

Ларс Гируп Бринк Нильсен
источник
localStorage и sessionStorage работают только для строковых значений.
HereToLearn_
Это верно, @HereToLearn_, но тогда вы можете использовать localStorage.foo = JSON.stringify({ arbitrary: 'object', meaning: 42, awesome: true });и var foo = JSON.decode(localStorage.foo);.
Ларс Гируп Бринк Нильсен
Что localStorageобщего с глобальными переменными?
Михал Перлаковский,
1
OP ищет решение этой проблемы: «Я хочу использовать переменную trailimage (объявленную в функции makeObj) в других функциях». Кто сказал, что решение должно включать глобальные переменные? Глобальные переменные редко являются хорошим решением для чего-либо.
Ларс Гируп Бринк Нильсен
0

Итак, вы хотите, чтобы переменная внутри функции была доступна вне функции? Почему бы не вернуть результаты переменной внутри функции? var x = function returnX { var x = 0; return x; }это идея ...

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

Я не проверял это, но если ваш код работал до этого небольшого изменения, то он должен работать.

ShanerM13
источник
0

использовать windowобъект не очень хорошая идея. Как я вижу в комментариях

  'use strict';

    function showMessage() {
        window.say_hello = 'hello!';
    }

    console.log(say_hello);

Это вызовет ошибку при использовании переменной say_hello, которую мы должны сначала вызвать showMessage function.

Маме
источник
-1

Вот пример кода, который может быть полезен.

  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 

Здесь я нашел хороший ответ: как можно объявить глобальную переменную в JavaScript

Шоханур Рахаман
источник
Хотя это может теоретически ответить на вопрос, было бы предпочтительным включить сюда основные части ответа и предоставить ссылку для справки.
Рохит Гупта
-1

Вот еще один простой способ сделать переменную доступной в других функциях без использования глобальных переменных:

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

makeObj();
someOtherFunction();

am2124429
источник
-2

если вы делаете функцию запуска, вы можете определить глобальные функции и переменные следующим образом:

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

Поскольку функция вызывается глобально с этим аргументом, здесь это глобальная область. Итак, что-то должно быть глобальным.

Константин Исаев
источник
thisнаходится undefinedв строгом режиме вне функции и не должен использоваться для ссылки на глобальный объект.
Михал Перлаковски