Контекст JavaScript - Предостережения
Если Вы объявляете переменную и забываете использовать ключевое слово var
, эта переменная автоматически делается глобальной переменной.
Таким образом, этот код сработал бы:
Это - плохая идея. Переменной, которая является глобальной переменной, можно изменить значение в любой другой части программы или любом другом сценарии. Это - нежелательно, поскольку может привести к непредвиденным побочным эффектам.
Во-вторых, Немедленно Выполняемое Функциональное Выражение обеспечивает способ избежать глобальных переменных. Вы можете встретить много библиотек, таких как jQuery, которые часто используют это:
(function() {
var jQuery = { /* Все методы идут здесь. */ };
window.jQuery = jQuery;
})();
Обертывание всего в функцию, которая затем сразу будет вызвана, означает, что все переменные в пределах этой функции связываются с локальным контекстом. В самом конце можно затем представить все свои методы, связывая объект jQuery
с window
, глобальным объектом.
Поскольку локальный контекст работает внутри функции, у любых функций, определяемых внутри других функций есть доступ к переменным, определенным во внешней функции:
Пример
var x = 5;
function inner() {
alert( x );
}
inner(); // 5
}
Попробуйте Сами »
Но у функции .outer()
нет доступа к любым переменным объявленным внутри .inner()
:
Пример
var x = 5;
function inner() {
alert( x );
var y = 10;
}
inner(); // 5
alert( y );
// Ошибка Доступа: y не определена
}
Попробуйте Сами »
Кроме того, переменные, которые объявляются в функции без ключевого слова var
не являются локальными для функции – JavaScript пересечет цепочку контекста полностью вплоть до контекста окна, чтобы обнаружить, где переменная была ранее определена. Если переменная не была ранее определена, она будет определена в глобальной области видимости, что может вызвать неожиданные последствия.
Пример
// опеределенным в том же контексте.
var foo = "привет";
var sayHello = function() {
console.log( foo );
};
sayHello(); // "привет"
console.log( foo ); // "привет"
Попробуйте Сами »
Переменные с тем же самым именем могут существовать в различных контекстах с различными значениями:
Пример
var sayHello = function() {
var foo = "привет";
console.log( foo );
};
sayHello(); // "привет"
console.log( foo ); // "мир"
Попробуйте Сами »
Когда Вы ссылаетесь на глобальную переменную в пределах функции, эта функция может видеть изменения в значении переменной после того, как функция определяется.
Пример
var foo = "привет";
var myFn = function() {
console.log( foo );
};
foo = "мир";
return myFn;
};
var f = myFunction();
f(); // "мир"
Попробуйте Сами »
Вот более сложный пример контекстов в действии:
Пример
var baz = 1;
var bim = function() {
console.log( baz );
};
bar = function() {
console.log( baz );
};
})();
Попробуйте Сами »
В этом примере, выполнение
console.log( baz );
// baz не опредена за пределами функции
Дает нам ReferenceError
. baz
была определена только в пределах функции, и никогда не фигурировала в глобальной области видимости.
bar(); // 1
.bar()
возможно, была определена внутри анонимной функции, но она была определена без ключевого слова var
, что означает, что она не была связана с локальным контекстом и вместо этого создавалась глобально. Более того у нее есть доступ к переменной baz
, потому что .bar()
был определена в пределах того же самого контекста, что и baz
. Это означает, что у нее есть доступ к этой переменной, даже при том, что другой код за пределами функции доступа не имеет.
bim(); // Ошибка Доступа: bim не определена
.bim()
была определена только в пределах функции, так что не существует в глобальном объекте, поскольку она было определена локально.