我有两个行为不同的示例页面,我想知道原因。对我来说,根据我收集的关于 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> </p>
</body>
</html>
在此示例中,demofunction 运行并将全局变量 z 设置为 5。alert 运行,由于作用域中没有 z,因此它会获取全局作用域并找到等于 5 的 z,因此会发出警报。然后定义一个名为 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。letSee() 运行并且警报(如果一致)应该看到没有名为第一个的局部变量,因此它应该向全局变量 6 发出警报。然后定义一个局部第一个,然后将其设置为 4。letsSee( ) 存在,最后打印打印全局第一个并再次显示 6。
但这并没有发生。发生的情况是它显示 6,警报未定义,并显示 6。我的问题是为什么它警报未定义而不是 6?如果我评论里面的行letSee forvar first;
然后我看到它警报 6,然后显示 4。这对我来说很有意义。但是为什么在警报之后首先使用该 var 会对警报调用所看到的值产生影响?特别是当它在 1.html 中没有产生任何影响时。
var
and function
声明是hoisted在执行任何代码之前。
function letsSee() {
alert(first);
var first;
first = 4;
}
表现得像
function letsSee() {
var first = undefined;
alert(first);
first = 4;
}
作为一个更容易理解的示例,您可以在声明函数之前调用函数:
foo(); // works!
function foo() { ... }
这是因为function
首先查看并提升声明,您可以在任何地方调用它,无论您在代码中声明它的时间/位置。使用声明的变量也会发生同样的情况var
。变量本身(name) 被吊起。写作var foo;
anywhere在给定范围内将产生任何更高范围的变量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
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)