Помогите с областью Javascript - PullRequest
1 голос
/ 30 октября 2010

Этот пример является упрощенной версией моего кода.Я все еще пытаюсь понять новый способ написания javascript (в отличие от 10-летней давности), поэтому спасибо за ваше терпениеМне нужно, чтобы значение globalVal было доступно, и у меня возникли проблемы.Значение получается из функции, которая вызывается в качестве аргумента другого метода.Пример, вероятно, легче увидеть.Просто нужно иметь возможность иметь доступ к globalvar из любой точки DOM.Это возможно?Спасибо

<html>
<head>
<script type="text/javascript">
    var globalvar;

    function initialize() { 
        var someVariable = 5;
        doSomething(someVariable, getTheVar);
    }

    function doSomething(someVariable, expectGlobalVar) {
        //alert(someVariable);
        alert(expectGlobalVar);
    }

    function getTheVar() {
        globalVar = "test"; 
        return globalVar;

    }
</script>
<title></title>
</head>
<body onload="initialize()">
    This is a test
</body>
</html>

Ответы [ 3 ]

1 голос
/ 30 октября 2010

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

В частности: при использовании var x; в области действия на уровне страницы (то есть вне какой-либо функции) объявляется свойство объекта window (у него есть особенность в том, что его нельзя удалить, но это не так важно здесь).

var foo = 2;
window.foo = 2; // Basically the same other than the delete thing we're not worrying about here

И так:

var foo = 2;
alert(foo);        // alerts "2"
alert(window.foo); // also alerts "2"
window.bar = 4;
alert(window.bar); // alerts "4"
alert(bar);        // also alerts "4"

Естественно, это верно только на верхнем уровне, вне каких-либо функций. Внутри функций вы объявляете что-то локальное для функции. (По сути, на самом деле это гораздо интереснее, чем это.)

Но так как вы спросили о области действия, ничего не стоит, что все остальные вещи, которые вы определили (initialize, getTheVar, doSomething), являются и глобальными. В общем, вы не должны помещать в глобальное пространство имен что-либо, что вы можете избежать.

По этой причине я рекомендую всегда использовать «функцию определения объема»:

(function() {
    // your code here
})();

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

В вашем случае вы сказали, что вам нужно globalVar, и вы также использовали initialize (хотя есть и другие способы сделать то, что вы делаете в initialize), так что вы можете сделать это:

(function() {
    var globalvar;

    // Exports
    window.globalVar = globalVar;
    window.initialize = initialize;

    // Implementation

    function initialize() { 
        var someVariable = 5;
        doSomething(someVariable, getTheVar);
    }

    function doSomething(someVariable, expectGlobalVar) {
        //alert(someVariable);
        alert(expectGlobalVar);
    }

    function getTheVar() {
        globalVar = "test"; 
        return globalVar;
    }
})();

Но вы можете пойти дальше. Поскольку вы не вызываете initialize до события load элемента body, вы можете избежать публикации initialize. Просто поместите свой тег сценария в конец документа, непосредственно перед закрывающим тегом </body> (как рекомендуют пользователи YUI ), и выполните инициализацию там:

<html>
<head>
<title>...</title>
</head>
<body>This is a test
<script type='text/javascript'>
(function() {
    var globalvar;

    // Initialization
    initialize();

    // Exports
    window.globalVar = globalVar;

    // Implementation
    function initialize() { 
        var someVariable = 5;
        doSomething(someVariable, getTheVar);
    }

    function doSomething(someVariable, expectGlobalVar) {
        //alert(someVariable);
        alert(expectGlobalVar);
    }

    function getTheVar() {
        globalVar = "test"; 
        return globalVar;
    }
})();
</script>
</body>
</html>

DOM полностью загружен и готов к работе в этот момент.

Но мы можем пойти еще дальше , если захотим: у нас может быть ничего в глобальном пространстве имен, если мы захотим. Если вы подключаете все свои обработчики в функции initialize вместо использования onload, onclick и подобных атрибутов, нет необходимости в том, чтобы globalVar был глобальным, кроме вашего кода. (Вы подключаете обработчики по факту, используя attachEvent [в IE], addEventListener [в основанных на стандартах браузерах] или, что еще лучше, используя такие библиотеки, как jQuery , Closure , Прототип , YUI или любой из нескольких других .)

0 голосов
/ 30 октября 2010

Вы должны вызывать функцию getTheVar вместо ее передачи:

function initialize() { 
        var someVariable = 5;
        doSomething(someVariable, getTheVar());
}
0 голосов
/ 30 октября 2010

Вы делаете это правильно .

Любая переменная, объявленная в глобальной области видимости, как и в примере, будет доступна из каждой области в окне.

(Кстати, объявление глобальной переменной [почти] эквивалентно window.myVar = someValue;)

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

doSomething(someVariable, getTheVar());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...