Подтвердить что ты не робот

Лучшая практика для объявления пустых переменных javascript

Есть ли что-то вроде лучшей практики, когда дело доходит до объявления переменных в javascript перед назначением им значения? Иногда это необходимо по причинам сферы действия, но что, если объем не имеет значения?

// Declare first
(function() {
    var foo = 'bar',
        a = 500,
        b = 300,
        c;

    // Some things get done here with a and b before c can use them...

    c = a * b;    

    // c is now ready to use...
    doSomething(c);
}());

// Declare when needed
(function() {
    var foo = 'bar',
        a = 500,
        b = 300;

    // Some things get done here with a and b before c can use them...

    var c = a * b; 

    // c is now ready to use...
    doSomething(c);
}());

И мне также интересно, что лучше всего подходит для чего-то подобного с объектными литералами:

// Add property with null assigned to it
var myObj = {
    foo: null,

    doSomething: function() {
        this.foo = 'bar';
    }
};

// Property gets added when value is set
var myObj = {
    doSomething: function() {
        this.foo = 'bar';
    }
};
4b9b3361

Ответ 1

Это в основном вопрос стиля.

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

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

Например:

for (var i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i);
    }, 0);
}

Так как var имеет область действия, все итерации (и функции внутри них) относятся к тому же i. Поскольку все три функции времени будут выполняться после завершения цикла, фрагмент над журналами 3 три раза.

Теперь для тех, кто имеет опыт работы с блоками, приведенное выше поведение не очень ясное. Перезапись фрагмента:

var i;
for (i = 0; i < 3; i++) {
    // ...
}

Теперь i объявляется в глобальной области, как и предыдущий фрагмент. Тем не менее, это гораздо более ясно.


Другое заблуждение:

(function() {
    if (true) {
        var foo = 1;
    } else {
        var foo = 1;
    }
}());

Опять же, в языках с блочной областью¹ это совершенно справедливо. Однако, поскольку объявления var поднимаются вверх до текущей области функции во время разбора, это эквивалентно:

(function() {
    var foo;
    var foo;
    if (true) {
        foo = 1;
    } else {
        foo = 1;
    }
}());

Переменная объявляется дважды. Большинство браузеров просто игнорируют второе объявление, и код будет "работать", но инструменты статического анализа кода, такие как JSHint, будут кричать на вас.

Вы можете переписать его только с одним объявлением, и это совершенно верно:

(function() {
    if (true) {
        var foo = 1;
    } else {
        foo = 1;
    }
}());

Но OCD-подобные кодеры, подобные мне, найдут это довольно уродливым. Итак, снова, объявив в верхней части области:

(function() {
    var foo;
    if (true) {
        foo = 1;
    } else {
        foo = 1;
    }
}());

Выглядит гораздо более аккуратно.


Опять же, это в основном вопрос стиля. Лично, если у меня есть гигантская функция, я ненавижу прокручивать весь путь, чтобы проверить, объявлена ​​ли переменная и добавлена ​​ли она в список. В этом случае я могу просто добавить пару объявлений var в середине функции (против рекомендации Крокфорда), которую мне лично легче читать и поддерживать.

Как бы то ни было, просто следите за тем, чтобы ваш код был наиболее удобным и понятным.


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

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


¹ Обратите внимание, что в JS 1.7 введены переменные с блочной областью через let, но он пока еще не поддерживается.к югу >