Обратите внимание: в отличие от C, C++ и Java, в JavaScript нет области види_ мости на уровне блоков. Все переменные, объявленные внутри функции, незави_ симо от того, где именно это сделано, определены во всей функции. В следующем фрагменте переменные i, j и k имеют одинаковые области видимости: все три оп_ ределены во всем теле функции. Это было бы не так, если бы код был написан на C, C++ или Java:
function test(o) {
var i = 0; // i определена во всей функции
if (typeof o == "object") {
var j = 0; // j определена везде, а не только в блоке
for(var k = 0; k < 10; k++) { // k определена везде, не только в цикле
document.write(k);
}
document.write(k); // k все еще определена: печатается 10
}
document.write(j); // j определена, но может быть не инициализирована
}
Правило, согласно которому все переменные, объявленные в функции, опреде_ лены во всей функции, может иметь удивительные следствия. Например:
var scope = "глобальная";
function f() {
alert(scope); // Показывает "undefined", а не "глобальная".
var scope = "локальная"; // Переменная инициализируется здесь,
// но определена она везде в функции.
alert(scope); // Показывает "локальная"
}
f();
Кто_то может подумать, что в результате первого вызова alert() будет напечата_ но слово «глобальная», т. к. инструкция var, объявляющая локальную перемен_
4.4. Элементарные и ссылочные типы
ную, еще не была выполнена. Однако согласно правилу определения областей видимости все происходит не так. Локальная переменная определена во всем те_ ле функции, значит, глобальная переменная с тем же именем скрыта во всем те_ ле функции. Хотя локальная переменная определена везде, до выполнения ин_ струкции var она не инициализирована. Поэтому функция f в предыдущем при_ мере эквивалентна следующему фрагменту:
function f() {
var scope;
//
Локальная
переменная определяется в начале функции
alert(scope);
//
Здесь она
существует, но имеет значение undefined
scope = "локальная"; // Здесь мы инициализируем переменную и присваиваем ей значение
alert(scope); // Здесь она уже имеет значение
}
Этот пример показывает, почему хорошая практика программирования подра_ зумевает помещение всех объявлений переменных в начале функции.