`
- 浏览:
34747 次
- 性别:
- 来自:
北京
-
在网上浏览的时候,看到一个题目,大约是这样的
- <script>
- var x = 1, y = z = 0;
- function add(n) {
- n = n+1;
- }
-
- y = add(x);
-
- function add(n) {
- n = n + 3;
- }
-
- z = add(x);
- </script>
问执行完毕后 x, y, z 的值分别是多少? 仔细看的人马上就知道了, x, y 和 z 分别是 1, undefined 和 undefined。 不过,如果将两个 add 函数修改一下,题目变为
- <script>
- var x = 1, y = z = 0;
- function add(n) {
- return n = n+1;
- }
-
- y = add(x);
-
- function add(n) {
- return n = n + 3;
- }
-
- z = add(x);
- </script>
那么这时 y 和 z 分别是什么呢?我马上想到是 2 和 4,不过结果却是 4 和 4。 这说明,在第一次调用 add 函数之前,第二个 add 函数已经覆盖了第一个 add 函数。原来,这是 JS 解释器的"预编译",JS 解析器在执行语句前会将函数声明和变量定义进行"预编译",而这个"预编译",并非一个页面一个页面地"预编译",而是一段一段地预编译,所谓的段就是一个 <script> 块。且看下面的代码
- <script>
- function add(n) {
- return n = n+1;
- }
- alert(add(1));
- </script>
-
- <script>
- function add(n) {
- return n = n+3;
- }
- alert(add(1));
- </script>
会分别弹出 2 和 4。 那么,将上面的题目再变换一下,如下
- <script>
- alert(typeof addA);
- addA();
- function addA() {
- alert("A executed!");
- };
- </script>
- <script>
- alert(typeof addB);
- addB();
- var addB = function() {
- alert("B executed!");
- };
- </script>
执行结果是什么呢? 按照前面的知识,第一个 <script> 块执行正常,结果就是弹出 "function" 和 "A executed!" 的对话框。 那么第二个 <script> 块呢? 执行结果是弹出 "undefined" 的对话框后报 JS 错误,说 addB 不是一个 function。 有点出乎意料?呵呵,其实第一个 script 块中的 addA 一句是函数声明,当然进行了"预编译",但是第二个 script 块中的 addB 一句并非函数声明。只不过在执行这段 <script> 之前对变量进行了"预声明",因此一开始变量addB是存在的,只不过是 undefined 的(可参看http://eclipse07.iteye.com/admin/blogs/484566)。因此执行结果便如上面所示。 将题目再变化下,如下
- <script>
- alert(typeof addB);
- addB();
- var addB = function addB() {
- alert("B executed!");
- };
- </script>
执行结果如何呢? 在 ff 下执行,与上面执行结果一样。打住,且在 IE6 下执行看看如何。 结果是弹出 "function" 和 "B executed!",一切正常。 Google 了一下,有人说这是 IE 的 BUG。 那么,请看下面的代码
- <script>
- alert(typeof addB);
- var addB = "variable";
- function addB() {
- alert("function addB");
- }
- alert(addB);
- </script>
执行结果是"function"和"variable"。 JS解析器先预定义了 addB 变量为 undefined, 但是 addB 函数覆盖了此变量,因此一开始执行结果是 function,然后 addB 被赋值为 "variable",因此最后执行结果是 "variable",上面的代码即使变为
- <script>
- alert(typeof addB);
- function addB() {
- alert("function addB");
- }
- var addB = "variable";
- alert(addB);
- </script>
结果也一样,这说明JS解析器先预声明变量,再预定义函数。 小结一下:JS 在执行前会进行类似"预编译"的操作,而且先预定义变量再预定义函数。
分享到:
Global site tag (gtag.js) - Google Analytics
相关推荐
NULL 博文链接:https://beck5859509.iteye.com/blog/505975
大家都知道JavaScript是解释型语言,既然是解释型语言,就是编译一行,执行一行,那又何来预编译一说呢?脚本执行js引擎都做了什么呢?今天我们就来看看吧。 1-JavaScript运行三部曲 语法分析 预编译 解释执行 语法...
JavaScript 预编译原理 今天用了大量时间复习了作用域、预编译等等知识 看了很多博文,翻开了以前看过的书(好像好多书都不会讲预编译) 发现当初觉得自己学的很明白,其实还是存在一些思维误区 (很多博文具有...
Packem是一个预编译的通用JavaScript模块捆绑器专注于性能灵活性和可扩展性
javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段,而在javascript中也有类似的“预编译阶段”(javascript的预编译是以代码块为范围[removed][removed],即每遇到...
// 若不执行函数,则不会进行函数预编译,d 就不会提升为全局变量 console.log(c); // error: c is not defined console.log(d); // 4 2. JavaScript执行过程 1. 语法分析,若存在低级语法错误,
下载 Bootstrap v4.5.0 版本的预编译文件,以便轻松地将其加入到你的项目中,其中包括:编译并压缩(minified)之后的 CSS 文件和编译并压缩(minified)之后的 JavaScript 插件
在 http://www.cnblogs.com/strick/p/3994209.html 有介绍说明,修正于2014.9.29
可以点出javascript方法,以及style的属性
JavaScript编译工具 绿色版,不用安装!
对JavaScript应用编译技术.pdf
将OpenCV预编译为针对node.js和deno环境JavaScript + WebAssembly。 :sauropod: 在此Wasm编译的OpenCV中,无需在计算机中安装OpenCV。 整个OpenCV库已经在此包中( opencv.js和opencv.wasm )。 该模块具有零依赖...
预编译课程笔记(晨哥哥)
js笔记,预编译/原型/
opencv.js该文件是编译好的opencv JavaScript版本,直接下载就可以使用。 opencv 的js实现,可以直接在网页中引用,可用于前端图像处理,速度极快!
JavaScript是解释性语言:解释一行,执行一行。 JS运行三部曲: 词法分析: 虽然JS是解释一行执行一行,但在解释执行之前会首先通篇扫描一遍查看有没有低级语法错误。 预编译: 发生在代码执行的前一刻。 解释执行:...
将Java编译成JavaScript 将Java编译成JavaScript 将Java编译成JavaScript