2

有没有办法在不同文件中的源代码之间进行函数和变量提升?也就是说,像

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

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

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

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

4

3 回答 3

5

我最初认为这是一个比实际看起来更有趣的问题。我认为这个问题的答案是每个<script>元素代表一个单独的Program,每个单独的 Program 在下一个 Program 发生任何事情之前都被解析和(至关重要)执行,因此提升的效果只能在单个 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>

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

于 2010-11-10T13:42:54.093 回答
1

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

window.foo = "bar";

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

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

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

“this”关键字只在函数内部有意义,它的值与函数来自的源文件无关(至少,没有任何直接意义)。

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

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

于 2010-11-10T13:27:37.070 回答
1

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

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

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

于 2010-11-10T14:18:57.397 回答