2014-05-04 3 views
0

Я два сниппеты, почему первый из них дает значение в то время как второе дает неопределенную?Почему иногда определение переменной после вызова переменной не дает undefined?

Отрывок 1:

function sayAlice() { 
    var sayAlert = function() { alert(alice); } 
    var alice = 'Hello Alice'; 
    return sayAlert; 
} 
var hi = sayAlice() ; 
hi();//alert Hello Alice 

Отрывок 2:

alert(i); // alert undefined 
var i = 1; 
+1

Переключить строки во втором примере, и он работает – Sebastian

+0

Да ... Я знаю. Я хочу знать, почему в первом фрагменте это сработало – Blake

+0

См. Ссылки, которые я представил в своем ответе, и вы узнаете. –

ответ

1

Это происходит потому, что во втором фрагменте, переменная «я» не определен в момент оповещения выполняется, но в первом фрагменте кода, что происходит в том, что в строке

var sayAlert = function() { alert(alice); } 

Вы определяют «sayAlert» как функцию, но эта функция не выполняется в этот момент. После этого вы определяете переменную «alice», после чего вы возвращаете «sayAlert», и в этот момент это когда выполняется предупреждение, а переменная «alice» уже имеет значение.

0

Попробуйте этот кусок кода, и вы получите совершенно другой результат ...

function sayAlice() { 
    var sayAlert = function() { alert(alice); } 
    return sayAlert; 
    var alice = 'Hello Alice'; 
} 

Потому что alice не определено при вызове функции. В вашем примере определяется alice.

1

Ваш вопрос:

Почему иногда определение переменной после вызова переменной не дать неопределенным?

Тогда вы обеспечиваете это как пример:

alert(i); // alert undefined 
var i = 1; 

Он предупреждает undefined, потому что вы выпускаете alert() перед тем i определены.

И в первом примере:

function sayAlice() { 
    var sayAlert = function() { alert(alice); } 
    var alice = 'Hello Alice'; 
    return sayAlert; 
} 
sayAlice()() //alert Hello Alice 

Такое же поведение можно ожидать, но это, кажется, как ваш нечетным способ вызова sayAlice происходит дважды с этим ()(). Что в основном означает, что это может произойти быстро, но первый вызов sayAlice() установит переменную alice, но, скорее всего, произойдет с alert на второй итерации через sayAlice()().

Ждать. Глядя на это снова, это то, что происходит в первом примере. Это просто определяет sayAlert как функцию, но на самом деле не запустить его:

var sayAlert = function() { alert(alice); } 

Но тогда вы сделаете это:

var alice = 'Hello Alice'; 

Который присваивает значение alice. И тогда вы, наконец, выполните следующее:

return sayAlert; 

Это происходит после первых двух предметов. Значит, на этой третьей линии у вас есть определенная функция, а затем определенная переменная, но она объединяется только в конечной строке.

Это имеет смысл для меня. Но sayAlice()() с двойным () кажется странным.

+1

У меня есть два фрагмента, первый не дает неопределенных, а второй делает – Blake

+0

@Blake Correct. Интересная головоломка. Посмотрите на мой анализ в последних изменениях. – JakeGould

+0

@JakeGould - Это не головоломка. Это документированное поведение JS 'закрытия'. –

1

Все объявления переменных перемещаются в верхнюю часть его области с помощью интерпретатора javascript перед запуском. Это значит, что-то вроде этого:

function sayAlice() { 
    var sayAlert = function() { alert(alice); } 
    var alice = 'Hello Alice'; 
    return sayAlert; 
} 
sayAlice()() //alert Hello Alice 

эквивалентно:

function sayAlice() { 
    var sayAlert, alice; 
    sayAlert = function() { alert(alice); } 
    alice = 'Hello Alice'; 
    return sayAlert; 
} 
sayAlice()() //alert Hello Alice 

При вызове sayAlice()() это первый решает sayAlice(), который возвращает вам функцию sayAlert, привязываться к переменной alice, которая имеет значение «Привет, Алиса». Пока внутренняя функция имеет доступ к внешней переменной, эта переменная сохранит свою область действия. Таким образом, строка после назначения sayAlert, то есть alice = 'Hello Alice', изменяет переменную, на которую ссылается функция sayAlert. Итак, в точке вызова вы получите ожидаемый результат «Привет Алиса».

+0

«Все объявления переменных перемещаются в начало области ...» Интересно. Посмотрите на мой ответ. Когда 'var sayAlert = function() {alert (alice); } 'не то, что переменной присваивается функция, но функция не выполняется до' return sayAlert; '? – JakeGould

+1

Я изменил свой ответ. Суть этого нет: переменная не назначена функции. Функция считывает ссылку на эту переменную, которая, возможно, была изменена в другом месте после объявления функции. – sahbeewah

+0

Хорошее объяснение! – JakeGould

1

У вас есть inside анонимная функция, которая является closure. Закрытие позволяет принести свою среду с ними и получить доступ к локальным переменным.

Этот MDN article описывает случай, очень похожий на ваш.

Также посмотрите на What exactly does “closure” refer to in JavaScript? SO сообщение.

Смежные вопросы