不同文件之间的吊装

时间:2010-11-10 13:22:24

标签: javascript hoisting

有没有办法在不同文件中存在的源代码之间执行函数和变量提升?就是这样的事情

//Inside firstfile.js
foo === "bar" //should return true

//Inside secondfile.js
function bar() {
    this.foo = "bar";
}

我想这是不可能的,因为大多数javascript引擎分别按顺序解析和执行不同的文件,但我不确定。

我不知道即使这是ECMA的规范,因为解析不同的文件并不是语言的一部分。

3 个答案:

答案 0 :(得分:3)

我原本以为这是一个比实际出现的更有趣的问题。我认为这个问题的答案是每个<script>元素代表一个单独的Program,在下一个程序发生任何事情之前,每个单独的程序都被解析并且(关键地)执行,因此提升的效果只能在一个程序中看到。

例如,在一个脚本中:

<script type="text/javasscript">
    alert(typeof foo);
    function foo() {}
</script>

...提醒“函数”,因为函数声明已被提升,但将这两行拆分为单独的<script>元素会改变这一点:

<script type="text/javasscript">
    alert(typeof foo);
</script>
<script type="text/javasscript">
    function foo() {}
</script>

...警告“未定义”,因为第一个脚本在第二个脚本被解析之前执行。

答案 1 :(得分:1)

单独加载的Javascript源都可以影响全局上下文。因此

window.foo = "bar";

在一个源文件中将允许另一个源(随后加载)检查:

if (window.foo === "bar") {
  // do something
}

这必须起作用,否则就不可能创建像所有流行的Javascript框架一样的东西。

“this”关键字仅在函数内部有意义,并且其值与函数所来自的源文件无关(至少在任何直接意义上都没有)。

编辑 - 我想这里有趣的是Javascript解释器行为(在问题中使用术语)“提升”函数声明在被评估的块中的其他代码之前。当浏览器加载它们时,这也是在逐个脚本的基础上完成的。因此,脚本块中的函数声明在每个块中的其他代码之前进行解释,但在加载和评估下一个<script>标记之前,将完整评估单个<script>标记。

如果你使用像LabJS或enhance.js这样的东西加载脚本,事情会变得更复杂,但是我不知道任何你可以依赖脚本“混合在一起”某种情况的上下文,除非您在服务器上明确地将它们组合在一起。

答案 2 :(得分:1)

浏览器遇到的所有脚本标记都会立即被解析和执行。这是因为document.write API可能需要浏览器向DOM输出内容。这意味着在这种情况下#script1必须在#script2之前完成。

<script id="script1"></script>
<script id="script2"></script>

您可能想要检查使用ASYNC和DEFER属性时的行为。 Webkit支持它们。