`
liu_87663663
  • 浏览: 36551 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Javascript的"预编译"思考

 
阅读更多

在网上浏览的时候,看到一个题目,大约是这样的 

Js代码  收藏代码
  1. <script>  
  2.    var x = 1, y = z = 0;  
  3.    function add(n) {  
  4.        n = n+1;  
  5.   }  
  6.   
  7.    y = add(x);  
  8.      
  9.    function add(n) {  
  10.       n = n + 3;  
  11.    }  
  12.   
  13.    z = add(x);  
  14. </script>  


问执行完毕后 x, y, z 的值分别是多少? 

仔细看的人马上就知道了, x, y 和 z 分别是 1, undefined 和 undefined。 

不过,如果将两个 add 函数修改一下,题目变为 
Js代码  收藏代码
  1. <script>  
  2.    var x = 1, y = z = 0;  
  3.    function add(n) {  
  4.       return n = n+1;  
  5.   }  
  6.   
  7.    y = add(x);  
  8.      
  9.    function add(n) {  
  10.       return n = n + 3;  
  11.    }  
  12.   
  13.    z = add(x);  
  14. </script>  

那么这时 y 和 z 分别是什么呢?我马上想到是 2 和 4,不过结果却是 4 和 4。 
这说明,在第一次调用 add 函数之前,第二个 add 函数已经覆盖了第一个 add 函数。原来,这是 JS 解释器的"预编译",JS 解析器在执行语句前会将函数声明和变量定义进行"预编译",而这个"预编译",并非一个页面一个页面地"预编译",而是一段一段地预编译,所谓的段就是一个 <script> 块。且看下面的代码 
Js代码  收藏代码
  1. <script>  
  2.    function add(n) {  
  3.       return n = n+1;  
  4.   }  
  5.    alert(add(1));  
  6. </script>  
  7.   
  8. <script>  
  9.    function add(n) {  
  10.       return n = n+3;  
  11.   }  
  12.    alert(add(1));  
  13. </script>  


会分别弹出 2 和 4。 

那么,将上面的题目再变换一下,如下 
Js代码  收藏代码
  1. <script>  
  2.    alert(typeof addA);  
  3.    addA();  
  4.    function addA() {  
  5.       alert("A executed!");  
  6.    };  
  7. </script>  
  8. <script>  
  9.    alert(typeof addB);  
  10.    addB();  
  11.    var addB = function() {  
  12.      alert("B executed!");  
  13.    };  
  14. </script>  


执行结果是什么呢? 按照前面的知识,第一个 <script> 块执行正常,结果就是弹出 "function" 和 "A executed!" 的对话框。 
那么第二个 <script> 块呢? 执行结果是弹出 "undefined" 的对话框后报 JS 错误,说 addB 不是一个 function。 
有点出乎意料?呵呵,其实第一个 script 块中的 addA 一句是函数声明,当然进行了"预编译",但是第二个 script 块中的 addB 一句并非函数声明。只不过在执行这段 <script> 之前对变量进行了"预声明",因此一开始变量addB是存在的,只不过是 undefined 的(可参看http://eclipse07.iteye.com/admin/blogs/484566)。因此执行结果便如上面所示。 

将题目再变化下,如下 
Js代码  收藏代码
  1. <script>  
  2.    alert(typeof addB);  
  3.    addB();  
  4.    var addB = function addB() {  
  5.      alert("B executed!");  
  6.    };  
  7. </script>  

执行结果如何呢? 
在 ff 下执行,与上面执行结果一样。打住,且在 IE6 下执行看看如何。 
结果是弹出 "function" 和 "B executed!",一切正常。 
Google 了一下,有人说这是 IE 的 BUG。 

那么,请看下面的代码 
Js代码  收藏代码
  1. <script>  
  2.    alert(typeof addB);  
  3.    var addB = "variable";  
  4.    function addB() {  
  5.        alert("function addB");  
  6.    }  
  7.    alert(addB);  
  8. </script>  

执行结果是"function"和"variable"。 
JS解析器先预定义了 addB 变量为 undefined, 但是 addB 函数覆盖了此变量,因此一开始执行结果是 function,然后 addB 被赋值为 "variable",因此最后执行结果是 "variable",上面的代码即使变为 
Js代码  收藏代码
  1. <script>  
  2.    alert(typeof addB);  
  3.    function addB() {  
  4.        alert("function addB");  
  5.    }  
  6.    var addB = "variable";  
  7.    alert(addB);  
  8. </script>  

结果也一样,这说明JS解析器先预声明变量,再预定义函数。 

小结一下:JS 在执行前会进行类似"预编译"的操作,而且先预定义变量再预定义函数。
分享到:
评论

相关推荐

    javascript预编译思考

    JavaScript预编译是一种优化代码执行效率的技术,尤其在大型项目中尤为重要。预编译的主要目的是在实际运行前处理代码,减少解析和运行时的负担,提高应用的性能。本篇文章将深入探讨JavaScript预编译的概念、重要性...

    JavaScript_Shadow是一个全新的web引擎,几乎完全是用JS从头开始制作的.zip

    5. 性能调优:为了克服JavaScript在系统级编程中的性能瓶颈,JavaScript Shadow可能采用了各种性能优化策略,例如代码分割、预加载、懒加载和资源缓存等,以提高页面加载速度和用户体验。 6. 模块化设计:鉴于...

    Color Connect Game using JavaScript with Source Code.zip

    JavaScript可以直接在浏览器中运行,无需预编译,这使得它成为快速构建功能的理想选择。 二、游戏框架 在"Color Connect Game"中,我们通常会使用HTML作为结构,CSS进行样式设计,而JavaScript则负责处理游戏逻辑...

    前端团队管理 前端基础架构的实践和思考 共22页.pdf

    * 静态文件预编译异常报告性能监测 * JS单元测试自动化功能测试 * CSS预处理(SCSS+Compass) * 模块依赖管理 * 图片无损压缩 * YUICompressor * Flash桌面onering文件加载 * Do.jsoz.js * Douban-JSLint * CSSLint ...

    Javascript-exercises

    这意味着开发者可以在运行时修改变量的数据类型,无需预编译,可以直接在浏览器环境中执行代码。 JavaScript主要应用在以下几个方面: 1. **DOM操作**:JavaScript可以通过Document Object Model (DOM) API来操作...

    TheEpiquestRep:用JavaScript制作的冒险游戏

    通过CoffeeScript编写的代码可以被编译成JavaScript,然后在浏览器环境中执行。 在游戏的开发过程中,开发者可能利用了JavaScript的DOM操作来实现游戏界面的动态更新,通过监听用户输入和事件处理函数来响应玩家的...

    尤雨溪-Vite 对下一代前端工具的思考.pdf

    新的 JS 编译器,如 esbuild 和 SWC,使得 Vite 能够快速编译和打包代码。 Vite 的技术挑战之一是 HTTP 请求开销的解决方案。Vite 使用 esbuild 进行依赖预打包,减少 HTTP 请求开销。Vite 也使用 HTTP header 缓存...

    第3章程序语言和语言处理程序基础知识.pdf

    此外,还有脚本语言如JavaScript,它既可以通过解释器实时执行,也可以通过编译器预编译。现代的编程语言往往具备了编译器和解释器的特性,比如Java的JVM和JavaScript的V8引擎,它们实现了即时编译(JIT),在运行时...

    jQuery-project:The Odin 项目的第二个项目 - Javascript 和 jQuery

    由于JavaScript是解释型语言,它可以直接嵌入HTML文档中,无需预编译,这使得其在网页开发中的应用极其便捷。 jQuery,作为JavaScript的一个库,由John Resig于2006年创建,旨在简化JavaScript的使用,尤其是处理...

    JSt-For-Fun:该项目是为练习JavaScript而创建的

    "JSt-For-Fun" 项目显然是一个专门为JavaScript初学者或爱好者设计的练习平台,旨在通过实践来提升JavaScript技能,同时也涉及到了React、HTML、CSS预处理器SCSS等相关技术。 React是Facebook开发的一个开源...

    多媒体技术及应用 — 课程学习

     3.6 G.722 SB-ADPCM编译码器  3.7 线性预测编码(LPC)的概念  3.8 GSM编译码器简介  练习与思考题  参考文献和站点 第4章 无损数据压缩  4.1 仙农-范诺与霍夫曼编码  4.2 算术编码  4.3 RLE编码  4.4 ...

    js代码优化演进(含个人分析)

    9. **预编译技术**:如使用Babel将ES6+代码转换为ES5,使得老版本浏览器也能正常运行。 10. **个人批注**:在学习过程中,对代码进行个人批注可以帮助理解作者的思路,同时也可以记录自己的思考和发现的问题,便于...

    WebPack工具运行原理及入门教程

    WebPack是什么 一个打包工具 一个模块加载工具 各种资源都可以当成模块来处理 ...如今,越来越多的JavaScript代码被使用在页面上,我们...思考:为什么只有JS需要被模块化管理,前台的很多预编译内容,不需要管理吗?

    JSP动态网站技术课程标准.docx

    此外,还会深入讲解JDBC技术,包括数据库连接、SQL语句的预编译,以及JavaBean的使用。 通过80课时的互动教学,学生将参与电子商城的各个页面开发,如首页、登录和注册页面。课程还将涵盖数据库操作,如数据的增删...

    计算机专业PHP相关毕业设计 源代码+论文

    涉及的知识点包括SQL查询、预编译语句、事务处理等。 3. **前端交互**:PHP与HTML、CSS、JavaScript的结合,实现页面动态效果和用户交互。可能用到AJAX异步请求,通过JSON数据格式进行前后端通信。 4. **框架应用*...

    前端开源库-node-sass-css-importer

    **前端开源库-node-sass-css-importer** 在前端开发中,CSS预处理器如Sass(Syntactically Awesome Style Sheets)极大地提升了...同时,它也鼓励我们思考如何利用预处理器的扩展能力来解决实际问题,提升开发效率。

    code.zip

    此外,它们也常用于软件的分发,例如开发者向其他开发者分享自己的代码库,或者提供给用户安装的预编译二进制包。 总的来说,“code.zip”是一个包含编程代码的压缩文件,它可能涵盖了多种编程语言,多层目录结构,...

    phper杂志第一期.rar

    4. **数据库交互**:介绍如何使用PHP与MySQL、PostgreSQL等数据库进行交互,包括SQL查询、事务处理、预编译语句等,对于实现数据存储和检索功能非常重要。 5. **PHP安全实践**:讲解防止SQL注入、XSS攻击、CSRF攻击...

    网页模板psd+HTML

    此外,了解如何使用前端构建工具(如Webpack或Gulp)自动化任务,如编译CSS和JS、压缩图片等,可以提升开发效率。 总之,“网页模板psd+HTML”是一个全面的前端学习资源,涵盖了从设计到开发的全过程。通过实践这样...

Global site tag (gtag.js) - Google Analytics