【发布时间】:2010-09-17 12:46:24
【问题描述】:
JavaScript 程序由语句和函数声明组成。执行 JavaScript 程序时,会发生以下两个步骤:
扫描代码以查找函数声明,以及每个 func。声明被“执行”(通过创建函数对象)并创建对该函数的命名引用(以便可以从语句中调用该函数)
语句按顺序执行(评估)(如它们在代码中出现的那样)
正因为如此,这工作得很好:
<script>
foo();
function foo() {
return;
}
</script>
虽然“foo”函数在声明之前被调用,但它之所以有效,是因为函数声明是在语句之前进行评估的。
但是,这不起作用:
<script>
foo();
</script>
<script>
function foo() {
return;
}
</script>
将抛出 ReferenceError(“未定义 foo”)。 这导致了这样的结论:网页的 HTML 代码中的每个 SCRIPT 元素都代表一个单独的 JavaScript 程序,并且每次 HTML 解析器遇到一个 SCRIPT 元素时,它都会执行该元素内的程序(然后一旦程序被执行,解析器转到 SCRIPT 元素后面的 HTML 代码)。
再说一遍,这确实有效:
<script>
function foo() {
return;
}
</script>
<script>
foo();
</script>
这里我的理解是全局对象(在全局执行上下文中作为变量对象)一直存在(并且一直存在),所以第一个 JavaScript 程序会创建函数对象并为它做一个引用,然后第二个 JavaScript 程序将使用该引用来调用该函数。因此,所有 JavaScript 程序(在单个网页内)“使用”同一个 Global 对象,并且一个 JavaScript 程序对 Global 对象所做的所有更改都可以被随后运行的所有 JavaScript 程序观察到。
现在,请注意...
<script>
// assuming that foo is not defined
foo();
alert(1);
</script>
在上述情况下,警报调用不会执行,因为“foo()”语句会抛出一个 ReferenceError(这会破坏整个 JavaScript 程序),因此,所有后续语句都不会执行.
但是,在这种情况下...
<script>
// assuming that foo is not defined
foo();
</script>
<script>
alert(1);
</script>
现在,警报调用会执行。第一个 JavaScript 程序抛出 ReferenceError (并因此中断),但第二个 JavaScript 程序正常运行。当然,浏览器会报错(虽然它确实执行了后续的JavaScript程序,但是在发生错误之后)。
现在,我的结论是:
- 网页的 HTML 代码中的每个 SCRIPT 元素都代表一个单独的 JavaScript 程序。这些程序在 HTML 解析器遇到它们时立即执行。
- 同一网页中的所有 JavaScript 程序“使用”同一个全局对象。该全局对象始终存在(从获取网页的那一刻起直到网页被销毁)。 JavaScript 程序可以操作 Global 对象,一个 JavaScript 程序对 Global 对象所做的所有更改都可以在所有后续 JavaScript 程序中观察到。
- 如果一个 JavaScript 程序中断(通过引发错误),这不会阻止后续 JavaScript 程序执行。
请对这篇文章进行事实核查,如果我有什么问题,请告诉我。
另外,我还没有找到解释这篇文章中提到的行为的资源,我认为浏览器制造商一定在某个地方发布了这些资源,所以如果你知道它们,请提供它们的链接。
【问题讨论】:
-
我从您的问题中删除了答案部分,因为它不属于那里。请随时将其发布为正确的答案。
标签: javascript browser hoisting