2010-12-10 3 views
2

У меня есть два примера страниц, которые ведут себя по-другому, и я хотел бы знать, почему. Для меня они, похоже, согласуются друг с другом, основываясь на том, что я собрал о просмотре в javascript.Теория переменных переменных Javascript

1.html:

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<script type="text/javascript"> 
    function demofunction(x, y) { 
    z=x+y; 
    } 
</script> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>4-6.htm</title> 
</head> 
<body> 
    <h1>Bad Scoping</h1> 
    <script type="text/javascript"> 
    //<![CDATA[ 
    demofunction(3, 2); 
    alert(z); 
    var z; 
    alert(z); 
    //]]> 
    </script> 
    <p>&nbsp;</p> 
</body> 

</html> 

В этом примере, запускает demofunction и задает глобальную переменную г до 5. прогонов оповещения и так нет г в области видимости она захватывает глобальный масштаб, и находит аз который равным 5, он предупреждает об этом. то определяется новая локальная переменная с именем z. второе предупреждение может видеть эту локальную переменную, но поскольку она не определена, она прерывает глобальную и снова сигнализирует 5.

2.html

<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <title>Bad Scoping</title> 
    <script type="text/javascript"> 
    //<![CDATA[ 
    first = 6; 
    document.writeln('<p>first is ' + first + "</p>"); 

    function letsSee() { 
    alert(first); 
    var first; 
    first = 4; 
    } 
    letsSee(); 
    document.writeln('<p>but now first is ' + first + "</p>"); 

    //]]> 
    </script> 
</head> 
<body> 
</body> 
</html> 

глобальный первым получает значение 6. letsSee() запускается и предупреждения (если соответствует) не должен видеть не локальную переменную с именем первого поэтому он должен предупредить глобальную переменную 6. затем сначала определяется локальная первая, которая затем устанавливается на 4. hasSee() существует, и последняя печать печатает глобальную первую и показывает 6 снова.

это НЕ произойдет. происходит то, что он показывает 6, предупреждение не определено, и показывает 6. мой вопрос направлен на то, почему он предупреждает о неопределенности, а не о 6? если я прокомментирую строку внутри letSee для var first;, я вижу, что она предупреждает 6, а затем отображает 4. это имеет смысл для меня. но почему возникает тот факт, что var сначала после предупреждения имеет значение для того, что видит сигнал предупреждения как значение? esp, когда это не повлияло на 1.html.

ответ

8

var10 и function объявления Поднял перед выполнением любого кода.

function letsSee() { 
    alert(first); 
    var first; 
    first = 4; 
} 

ведет себя как

function letsSee() { 
    var first = undefined; 
    alert(first); 
    first = 4; 
} 

В качестве более легкого понимания, например, вы можете вызывать функции, прежде чем они объявлены:

foo(); // works! 
function foo() { ... } 

Это происходит потому, что function декларация посмотрел на первую и вы можете вызывать его везде, независимо от того, когда/где в коде вы его объявляете. То же самое происходит с переменными, объявленными с использованием var. Сама переменная (имя) поднята. Написание var foo;в любом месте в пределах данной области действия сделает любую более высокую область переменной foo недоступной в пределах этой области.

var foo = 'foo'; 

function() { 
    alert(foo);  // All of these can't see the higher-scoped 
    doSomething(foo); // foo = 'foo' variable, because the 
    return foo;  // local foo has already been hoisted. 

    var foo; // masks the higher-scoped foo within the entire scope, 
       // even if it doesn't appear to be executed 
} 
+1

Черт вас, господин быстро! +1 – alex 2010-12-10 04:56:16

0

Я думаю, что это потому, что объявления функций водрузили в JavaScript - то, что функция работает до вершины, где это переменные вы пытаетесь получить доступ не определен.

3

Есть две вещи, которые бросают тебя

1. вашего предположения, что <script>...</script> блок имеет свою область применения, как функция имеет объем. По правде говоря, все блоки <script> существуют в одной и той же глобальной области.

2. вы также предположили, что объявление var происходит в том порядке, в котором оно отображается в коде. По правде говоря, все var s в данной области выполняются на , начинающемся этой области. (-edit- только для уточнения: декларация var происходит в начале области действия, но любая операция присваивания остается в ее исходном месте в коде. Значение переменной, которая была объявлена, но еще не имела значения назначен undefined).

Итак ... в первом примере, var z фактически объявляя z в области по глобальной, то вызов demofunction() работает на этой глобальной z, и оба предупреждения работать против же глобальной z.

Принимая во внимание, что во втором примере first изначально задан в глобальной области действия, затем снова объявлен в пределах функции. В функции, предупреждение и назначение оба действуют на местных переменной. Вне функции writeln() s работают с глобальной переменной.

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