js: объявления var, циклы, эффективность, полезность - PullRequest
3 голосов
/ 19 мая 2011

читаемость в сторону ... с точки зрения эффективности и / или функциональности, я не ясно о разнице между размещением объявления снаружи (моя практика) или внутри цикла (замечено в других сообщениях SO). или в этом отношении, почему декларации кода вообще? Вот несколько вырожденных примеров ... больше комментариев ниже.

A1:

var x;
for (i=0; i<10; i++){
    x = i;
 }

A2

for (i=0; i<10; i++){
    var x = i;
 }

B1

var i;
for (i=0; i<10; i++){
 }

B2:

for (var i=0; i<10; i++){
 }

С1:

var x;
var y;

С2:

var x, y;

читаемость в сторону ... Я подозреваю, что нет разницы между B1 и B2 и между C1 и C2, но опасаюсь эффективности или функциональной разницы между A1 и A2. Кроме того, я не уверен, какие преимущества существуют для объявлений вообще, за исключением использования объявлений в функциях для устранения (?) возможного конфликта с глобальной переменной с тем же именем.

РЕДАКТИРОВАТЬ: добавил пару точек с запятой

РЕДАКТИРОВАТЬ: ясность первого предложения, функция изменилась на функциональность

РЕДАКТИРОВАТЬ: добавив код ниже, чтобы помочь в комментарии ниже, что я сделал РЕДАКТИРОВАТЬ: комментарии

<!doctype html>
<html>
<head>
<script type='text/javascript'>
var w = (function(){  // wrapper
    alert('init');
    function p(){ // private
        alert('p');
        w.b(); //needs prefix
    }
    return{
        a: function(){ // public
            alert('a'); 
            p();
            w.b(); // needs prefix 
        },
        b: function(){ // public
            alert('b'); 
        }
    };
})(); // execute immediately
</script>
<script type="text/javascript">window.onload=w.a;</script>
</head>
<body>
sequence of alerts will be 'init' 'a' 'p' 'b'
</body>
</html>

Ответы [ 4 ]

3 голосов
/ 19 мая 2011

Объявления переменных поднимаются до верха функции.Это не будет иметь никакого значения, если, конечно, вы не говорите об объявлении переменной в новой области видимости функции.


РЕДАКТИРОВАТЬ: Сначала не заметил, вашпервый пример не объявлял i с var.Это не очень хорошая практика.


РЕДАКТИРОВАТЬ:

Как правило, рекомендуется избегать создания глобальных переменных, чтобы избежать конфликтов с другими сценариями, которые могут устанавливать глобальные переменные.

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

Единственный способ создания новой области видимости переменной в JavaScript - это тело функции.Функции могут быть вложенными друг в друга, создавая цепочку областей видимости, которая начинается с самой внутренней функции и заканчивается глобальной областью видимости.

Из-за этого, как правило, весь ваш код помещается в вызываемую функциюнемедленно.Таким образом, любые переменные, которые вы создаете с помощью var, не будут в конечном итоге глобальными.

(function() {   // <-- create a function

    // place your code in here

      // use "var" when declaring variables so they don't become global
    var name = "patrick dw";

    alert( name );

})(); // <-- invoke the function immediately so your code runs

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

Поскольку обход области видимости переменной требует некоторых ресурсов, люди часто вызывают эту функцию с некоторыми передаваемыми аргументами, такими как window.

(function( window, undefined ) {

      // now the window object is referenced locally. Better for performance.

    var name = "patrick dw";

    alert( name );

})( window ); // <-- invoke the function passing in the global "window" object

Теперь на объект window ссылаются локально внутри вашей функции, поэтому, если вы получите доступ к какому-либо свойству window, ему не придется полностью следовать цепочке областей действия за пределами вашей функции.

Я также включил в функцию дополнительный параметр undefined, но не передал ему аргумент.Это должно помочь избежать странной проблемы, вызванной некоторыми плохими методами кодирования.Но это еще одна проблема.

Теперь, взяв ту же функцию, если бы мы не использовали var при объявлении нашей переменной name, она автоматически стала бы глобальной.Я обновлю пример и добавлю еще одну область действия функции для иллюстрации.

(function( window, undefined ) {

          // create a function 
    function some_func() {

        name = "patrick dw";  // didn't use "var" when declaring!!
        alert( name );
    }

    some_func();  // call our function

    alert( window.name ); // but "name" is also accessible from the global window

})( window );

alert( name ); // outside those functions, we're global, and again we can see that
               //   the "name" variable is accessible

Итак, как вы можете видеть, мы никогда не объявляли var name, поэтому она стала автоматической глобальной переменной, даже если онабыло вложено две функции глубиной.

Это источник многих ошибок, и это причина, почему вы должны быть очень осторожны, чтобы использовать var.


Наконец, я быобратите внимание, что ECMAScript 5 запрещает некоторые плохие практики кодирования при запуске вашего кода в "strict mode";.Не многие браузеры в настоящее время реализуют strict mode, но было бы полезно периодически проверять ваш код в одном из них.

Вот таблица совместимости для ECMAScript 5 .Строгий режим находится внизу.Вы увидите, что Firefox 4 поддерживает его.

Вот пример:

(function( window, undefined ) {

    "strict mode"; // <-- use the strict mode directive

    name = "patrick dw";  // In Firefox 4, you should get a ReferenceError in the console
                          //   because "name" was never declared with "var"
})( window );
1 голос
/ 19 мая 2011

все это только синтаксические различия.Я думаю, что даже в B обе декларации находятся в одной области.

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

В основном речь идет о том, какой вариант лучше всего подходит к ситуации, в то же время он должен оставаться максимально последовательным.

Если у вас уже есть глобальная переменная x, я не думаю, что что-либо из этого предотвратит столкновение.

0 голосов
/ 19 мая 2011

Функциональной разницы или эффективности между A1 или A2 также нет. Попробуйте это:

var arr=[];
for(var i=0; i<10; ++i) {
  var x=i;
  arr.push( function() {alert(x);} );
}
for(var i=0; i<10; ++i) {
  arr[i]();
}

Вы увидите, что значение, показанное всеми функциями, одинаково, потому что это тот же самый x, который используют все функции. Новая переменная не создается каждый раз.

0 голосов
/ 19 мая 2011

Область действия переменной javascript совместно используется со всей функцией при использовании var, поэтому не будет никакой разницы между A1 и A2, когда они оба находятся в функции.

Однако вы можетеиспользуйте ключевое слово let и ограничьте область действия этих переменных блоком, например:

for(let x = 0; x < 10; x++){}

Это ограничит переменную x только областью действия в блоке for {}.

...