if ("a" in window) {
var a = 1;
}
alert(a);
Одному. Посмотрим, почему.
На стадии подготовки к выполнению, из var a
создается window.a
:
// window = {a:undefined}
if ("a" in window) { // в if видно что window.a уже есть
var a = 1; // поэтому эта строка сработает
}
alert(a);
В результате a
становится 1.
var
)?if ("a" in window) {
a = 1;
}
alert(a);
Ошибка.
Переменной a
нет, так что условие "a" in window
не выполнится. В результате на последней строчке - обращение к неопределенной переменной.
if ("a" in window) {
a = 1;
}
alert(a); // <-- error!
var
, а ниже есть)?if ("a" in window) {
a = 1;
}
var a;
alert(a);
Одному.
Переменная a
создается до начала выполнения кода, так что условие "a" in window
выполнится и сработает a = 1
.
if ("a" in window) {
a = 1;
}
var a;
alert(a); // 1
var a = 5;
function a() { }
alert(a);
5.
Чтобы понять, почему — разберём внимательно как работает этот код.
a
и функция a
. Стандарт написан так, что функция создаётся первой и переменная ее не перезаписывает. То есть, функция имеет приоритет.a = 5
,
перезаписывая a
, и уже не важно, что там лежало.alert(a)
выводит 5.var value = 0;
function f() {
if (1) {
value = true;
} else {
var value = false;
}
alert(value);
}
f();
Изменится ли внешняя переменная value
?
P.S. Какими будут ответы, если из строки var value = false
убрать var
?
Результатом будет true, т.к. var
обработается и переменная будет создана до выполнения кода.
Соответственно, присвоение value = true
сработает на локальной переменной, и alert
выведет true.
Внешняя переменная не изменится.
P.S. Если var
нет, то в функции переменная не будет найдена. Интерпретатор обратится за ней в window и изменит её там.
Так что без var
результат будет также true, но внешняя переменная изменится.
function test() {
alert(window);
var window = 5;
alert(window);
}
test();
Результатом будет undefined, затем 5.
Директива var
обработается до начала выполнения кода функции. Будет создана локальная переменная, т.е. свойство LexicalEnvironment:
LexicalEnvironment = {
window: undefined
}
Когда выполнение кода начнется и сработает alert
, он выведет локальную переменную.
Затем сработает присваивание, и второй alert
выведет уже 5.
var a = 5
(function() {
alert(a)
})()
P.S. Подумайте хорошо! Здесь все ошибаются! P.P.S. Внимание, здесь подводный камень! Ок, вы предупреждены.
Результат - ошибка.
Дело в том, что после var a = 5
нет точки с запятой.
JavaScript воспринимает этот код как если бы перевода строки не было:
var a = 5(function() {
alert(a)
})()
То есть, он пытается вызвать функцию 5, что и приводит к ошибке.
Если точку с запятой поставить, все будет хорошо. Это один из наиболее частых и опасных подводных камней, приводящих к ошибкам тех, кто не ставит точки с запятой.
name
через замыкание в примере ниже?name
из памяти при выполнении delete donkey.sayHi
? Если нет — можно ли к name
как-то обратиться после удаления donkey.sayHi
?donkey.sayHi = donkey.yell = null
— останется ли name в памяти?var makeDonkey = function() {
var name = "Ослик Иа";
return {
sayHi: function() {
alert(name);
},
yell: function() {
alert('И-а, и-а!');
}
};
}
var donkey = makeDonkey();
donkey.sayHi();
[[Scope]]
на внешний объект переменных, которая будет присвоена функциям sayHi
и yell
при создании объекта.name
не удалится из памяти, поскольку несмотря на то, что sayHi
больше нет, есть ещё функция yell
, которая также ссылается на внешний объект переменных. Этот объект хранится целиком, вместе со всеми свойствами.
При этом, так как функция sayHi
удалена из объекта и ссылок на нее нет, то больше к переменной name
обращаться некому. Получилось, что она «застряла» в памяти, хотя, по сути, никому не нужна.sayHi
и yell
удалить, тогда, так как больше внутренних функций не останется, удалится и объект переменных вместе с name
.