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 - Переменная Instantiation (нижняя часть стр.37) в ECMA-262 , спецификация JS.