Skip to content

第 12 期(2019-05-19):同名函数的执行 #14

@wingmeng

Description

@wingmeng

类型:基础知识
难度:★

有以下 html 文件,请问运行后浏览器控制台输出结果是什么?为什么?

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    function fn() {
      console.log(1);
    }
    fn();

    function fn() {
      console.log(2);
    }
    fn();
  </script>
  <script>
    function fn() {
      console.log(3);
    }
    fn();
  </script>
</body>
</html>

参考答案:

控制台依次输出:2, 2, 3

原因:JavaScript 解释器在执行页面脚本时,是按块执行的。具体来讲,就是当浏览器在解析 HTML 文档时,如果遇到一个 script 标签,则 JavaScript 解释器会等到这个代码块都加载完成后(读取到当前代码块的 </script> 标签),先对代码块进行预编译,然后再执行。执行完毕后,浏览器会继续解析下面的 HTML 文档,同时JavaScript 解释器也准备好处理下一个代码块……

上面代码的执行步骤:

  1. 读入第一个代码块(代码块指 <script></script> 中的代码,下同);
  2. 做语法分析,如有语法错误,则报错并停止当前代码块里后续代码的执行,跳到第 5 步;
  3. 对代码块内的所有变量和函数做预编译处理(这里有 2 个重名的 fn 函数,后面一个会覆盖前面一个函数的定义);
  4. 执行代码(这段代码里调用了 2 次 fn(),故依次输出 22);
  5. 读入第二个代码块;
  6. 重复 2 ~ 4,输出 3

题外话:如果 script 标签带有 deferasync 属性,情况有所不同。

相关资料:https://www.jianshu.com/p/bda5266755a2


本期优秀回答者: @AMY-Y

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions