JavaScript делает пару вещей, которые, очевидно, не являются интуитивными — тот, который вас интересует, называется «подъемом» — JS перемещает объявления var в начало функции, где они служат единственной цели резервирования этого имени переменной как локальная переменная в области видимости функции. Иногда это приводит к множеству странностей. Если имя переменной уже зарезервировано как локальная переменная (например, это аргумент), объявление var полностью удаляется.
Еще одна неинтуитивная часть JS — это то, как он работает с переменными-аргументами и объектом arguments (которые, как показал Бегемот, немного особенные). Однако это не обязательно то, что вас интересует - для вашего примера важно то, что аргументы также объявляют это имя переменной как локальное для функции.
Результатом всего этого является то, что когда у вас есть var f, а также имя аргумента f, `var f' отбрасывается, и ваш пример эквивалентен:
function Foo(f) {
f = f;
}
Вы можете увидеть это на примере Бегемота, потому что:
function foo(f) {
console.log(f); // --> 11
console.log(arguments); // --> array [11]
var f = 10;
console.log(f); // --> 10
console.log(arguments); // --> [10] (!!!)
}
Эквивалентно:
function foo(f) {
var f;
console.log(f); // --> 11
console.log(arguments); // --> array [11]
f = 10;
console.log(f); // --> 10
console.log(arguments); // --> [10] (!!!)
}
Эквивалентно:
function foo(f) {
console.log(f); // --> 11
console.log(arguments); // --> array [11]
f = 10;
console.log(f); // --> 10
console.log(arguments); // --> [10] (!!!)
}
Дополнительные сведения см. в разделе 10.1.3 — Создание переменных (внизу стр. 37) в ECMA-262, спецификация JS.
person
Andrey Fedorov
schedule
19.03.2009