Теория переменных Javascript - PullRequest
       0

Теория переменных Javascript

2 голосов
/ 10 декабря 2010

У меня есть два примера страниц, которые ведут себя по-разному, и я хотел бы знать, почему. Мне кажется, они согласуются друг с другом, основываясь на том, что я собрал в области видимости в 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>

В этом примере демофункция запускает и устанавливает глобальную переменную z равной 5. запускается оповещение, и поскольку в области нет z, она захватывает глобальную область и находит z, равное 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>

global first устанавливается на 6. выполняется,4 . Let'sSee () существует, и последний отпечаток сначала печатает глобал и снова показывает 6.

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

Ответы [ 3 ]

8 голосов
/ 10 декабря 2010

var и 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
}
3 голосов
/ 10 декабря 2010

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

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

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

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

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

0 голосов
/ 10 декабря 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...