Знаете ли вы JavaScript
У Дмитрия Барановского (это автор Raphaël —
Итак, что выведет каждый кусок кода?
if (!("a" in window)) {
var a = 1;
}
alert(a);var b = function a(x) {
x && a(--x);
};
alert(a);function a(x) {
return x * 2;
}
var a;
alert(a);function b(x, y, a) {
arguments[2] = 10;
alert(a);
}
b(1, 2, 3);function a() {
alert(this);
}
a.call(null);
Комментарии 38
А как последний работает и какой смысл во втором?
Тайный смысл второй конструкции я совсем не понял.
В третьем для меня было не очевидно, что var не переинициализирует переменную.
В четвёртом логично, что a и arguments[2] — это ссылка на одно и то же значение. Иначе попадаем на память.
В пятом: this в глобальной области указывает на window. Вызов call() у функции с параметром null равнозначно вызову call() без аргументов. А без аргументов вызываемая функция не «биндится» ни к какому объекту (или «биндится» к «объекту по умолчанию» — window).
Я всё так это понимаю.
Может я
Вот этот код алертит один раз undefined.
Теперь убери «var» (alert оставь), тебе по прежнему кажется, что ты понимаешь как это работает?
Вот ещё забавно:
if (!(«a» in window)) {
alert( 'no' );
}
alert(window.a);
Получается что не важно где задаётся var a или window.a, оно инициализируется в любом случае.
Точно также, конструкция function f () {} объявляет функцию во всей лексической области видимости, вне зависимости от того, на какой конкретно строчке находится эта конструкция.
Например, функцию можно объявить уже после ее использования:
alert (f (5))
function f (x) {return (x*x)}
Или даже на той строчке, на которую никогда не ступит нога интерпретатора:
if (false)
{
function f (x) {return (x*x)}
}
alert (f (5))
Главное, чтобы функция или переменная использовалась в той области лексической видимости, где объявлялась.
здесь это важно понимать )))
Комментарий для zeroglif.livejournal.com:
Какие браузерыкак-то иначе воспринимают эту конструкцию?
В IE он выведет тело функции, а вот мой основной браузер (Opera 10) скажет, что там ошибка (нет переменной «а»).
Т.е. такой пример сработает:
alert (f (5))
function f (x) {return (x*x)}
А вот такой уже нет (даже с условием true):
alert (f (5))
if (true)
{
function f (x) {return (x*x)};
}
Однако, если функция находится НЕ во вложенном блоке, то она БУДЕТ объявлена. Даже если до ее строчки интерпретатор заведомо никогда не дойдет:
function main ()
{
alert (f (5));
return;
function f (x) {return (x*x)};
}
main ();
b = function a() { …по имени «a» функцию видно только здесь }
…а здесь undefined (если выше не определили)
Забавно, спасибо. Как я уже говорил, в «Опере» это не так.
У меня в FF второй пример не делает вообще ничего. Даже алерт не выбрасывает.
Возможно,
alisey.myopenid.com написал всё правильно, кроме последней строчки. Да, действительно имя a видно только внутри функции, поэтому снаружи функции такое имя вообще не задано, и опера выдаёт Undefined variable: a. То есть, «такого имени в scope вообще нет», а не «такое имя есть, но значение ему не присвоено»
а, ну да, показывается это сообщение не в алёрте, а в консоли
имхо
Возможно. Очень обидно, что в таких вещах браузеры ведут себя
имхо, примеры, начиная с третьего — ошибки, глумление над программированием, которое нельзя использовать в практике, поэтому всё равно, что как браузеры обрабатывают эти ошибки
Что бы вы понимали вообще в программировании програм.
Эти примеры нужны для того, чтоб понимать что происходит с вашим кодом и как именно устроен ваш инструмент.
если вы в своём коде объявляете переменные и функции с одинаковыми названиями, то вы не гуру. То, что браузер не называет это ошибкой, ещё не означает, что так можно делать.
Да, всё ещё понимаю =)
JS интерпретируется как бы в 2 этапа.
Сначала создаются «глобальные» объекты -- функции, глобальные переменные и т.п. Потом выполняется код. Это и позволяет определять функции в произвольном месте кода, в том числи позже первого использования.
Вижу, об этом выше уже написали.
Комментарий для sergeybelov.ru:
Это не только глобального контекста касается, внутри функций всё происходит аналогичным образом.
Комментарий для www.alik.su:
Всё так, я просто обратил внимание на то, что и у вас, и у автора теста были приведены неоднозначные (браузерозависимые) примеры. Результат будет зависить от консоли. ;)
Ну, это мой первый комментарий в этом посте.
Действительно второй пример в IE отрабатывает неправильно. Можно в начале написать var a = 1; тогда результат будет одинаковый. Там был ещё один пример изначально: alert(1 in [,,2]), но пришлось убрать
Ещё буквально вчера добавил:
var a = 5;
a.t = 3;
alert(a.t);
Усилить хочется:
var a = 5;
alert(a.t = 3);
alert(a.t);
Хорошее дополнение :)