2016-02-26 2 views
2

Посмотрите на следующий фрагмент кода:Неопределенная переменная в функции

var fruit = "Orange"; 
echoThis(); 

function echoThis() {  
    alert(fruit); 
    var fruit = "Apple"; 
} 

Когда я запускаю этот фрагмент кода, предупреждение о fruit является undefined. Зачем?

Сначала я думал, что это имеет какое-то подъемным, что в Funciton, двигатель JS «поднимает» все var объявления к вершине или что-то, но тогда я бы ожидать оповещения для отображения Apple, не undefined.

Возможно, существует некоторое элементарное поведение JS, о котором я не знаю. Кто-нибудь должен объяснить?

JS скрипку: https://jsfiddle.net/z37230c9/

+0

Вы должны передать плод в качестве аргумента функции. Или сделайте свою переменную «фрукты» публичной, удалив «var» –

+0

Я знаю, как я могу заставить ее работать. Теперь я просто пытаюсь понять, почему он ведет себя так. – Weblurk

ответ

6

Это из-за hoisting. Переменные, объявленные в функции, доступны для всей области действия, но им присваивается значение, которое вы указали.

Это:

function echoThis() {  
    alert(fruit); 
    var fruit = "Apple"; 
} 

становится этим:

function echoThis() {  
    var fruit; 
    alert(fruit); 
    fruit = "Apple"; 
} 

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

также:

var fruit = "Orange"; //this fruit variable 
echoThis(); 

function echoThis() {  
    alert(fruit); 
    var fruit = "Apple"; // is overridden by this, 
    //because it's re-declared in a local scope. 
} 

, если вы действительно хотите изменить это, то удалите var в функции.

function echoThis() {  
     alert(fruit); 
     fruit = "Apple"; //this now accesses the global fruit. 
    } 
+0

Отличный ответ, спасибо. Я не пытался выполнить что-либо конкретное, кроме обучения JS поведения здесь. Итак, в основном ответ на мой вопрос: объявления Var поднимаются, но переменные присваивания нет? – Weblurk

+0

Да, вот как это работает. – kemiller2002

+1

Кроме того, объявления функций будут полностью подняты; выражения функции, просто имя переменной (как указано выше). – Andy

0

Это потому, что js имеет лексический охват и подъем.

так echoThis ищет fruit внутри себя, прежде чем искать снаружи и поскольку у вас есть var fruit = "Apple";, fruit поднято в echoThis.

+0

Я не думаю, что лексический охват имеет к этому какое-то отношение. http://pierrespring.com/2010/05/11/function-scope-and-lexical-scoping/ – Cristy

3

Переменная поднимается в верхней части функции при ее компиляции.

function echoThis() {  
    alert(fruit); 
    var fruit = "Apple"; 
} 

Translates to this 

function echoThis() {  
    var fruit; 
    alert(fruit); 
    fruit = "Apple"; 
} 

Так что, когда вызывается предупреждение, оно технически не определено на данном этапе. Чтобы перестать видеть это, переместите объявление переменной перед оператором оповещения.

+0

Все верно, но почему только «вардовые фрукты» подняты, а не «var fruit =« Apple »? – Weblurk

+1

Только переменная декларации поднимаются, но не присваиваются .. вот как работает компилятор –

+1

@Weblurk Потому что только декларации поднимаются, а не присваиваются. – Cristy

0

Помимо вышеуказанных ответов, если вы хотите, чтобы получить оранжевый и яблоко после .. вы могли бы попытаться передать переменную просто в качестве параметра и работы в функции

var fruit = "Orange"; 
 
echoThis(fruit); 
 

 
function echoThis(fruit) { 
 
    alert(fruit); // You will get the orange 
 
    var fruit = "Apple"; 
 
    alert(fruit); // You will get the apple 
 
}

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