Javascript范围变量理论

Ank*_*kur 2 html javascript scope

我有两个行为不同的示例页面,我想知道原因.对我而言,他们似乎基于我收集的关于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>
Run Code Online (Sandbox Code Playgroud)

在此示例中,demofunction运行并将全局变量z设置为5.警报运行并且由于范围中没有z,它会抓取全局范围并找到等于5的az,它会发出警报.然后定义一个名为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>
Run Code Online (Sandbox Code Playgroud)

全局优先设置为6. letsSee()运行并且警报(如果一致)应该看不到名为first的局部变量,因此它应该警告全局变量6.然后定义本地第一个,然后设置为4. letsSee( )存在并且最后一个打印首先打印全局并再次显示6.

但这不会发生.会发生什么,它显示6,警报未定义,并显示6.我的问题是针对为什么它提醒undefined而不是6?如果我在letSee for i中注释该行,var first;则会看到它警告6然后显示为4.这对我来说很有意义.但为什么在警报之后首先使用var会对警报调用所看到的值产生影响?特别是当它在1.html中没有任何区别时.

dec*_*eze 8

var并且在执行任何代码之前都会提升function声明.

function letsSee() {
  alert(first);
  var first;
  first = 4;
}
Run Code Online (Sandbox Code Playgroud)

表现得像

function letsSee() {
  var first = undefined;
  alert(first);
  first = 4;
}
Run Code Online (Sandbox Code Playgroud)

作为一个更容易理解的示例,您可以在声明函数之前调用它们:

foo();  // works!
function foo() { ... }
Run Code Online (Sandbox Code Playgroud)

这是因为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
}
Run Code Online (Sandbox Code Playgroud)