`
liukemin
  • 浏览: 8344 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JavaScript预编译与执行顺序的关系

 
阅读更多
在Javascript中,function才是Javascript的第一型。当我们写下一段函数时,其实不过是建立了一个function类型的实体。
就像我们可以写成这样的形式一样:

function Hello() {
    alert("Hello");
}
Hello();
var Hello = function() {
    alert("Hello");
}
Hello();

其实都是一样的。
但是当我们对其中的函数进行修改时,会发现很奇怪的问题。
function Hello() {
    alert("Hello");
}
Hello();
function Hello() {
    alert("Hello World");
}
Hello();

我们会看到这样的结果:连续输出了两次Hello World。而非我们想象中的Hello和Hello World。
这是因为Javascript并非完全的按顺序解释执行,而是在解释之前会对Javascript进行一次“预编译”,在预编译的过程中,会把定义式的函数优先执行,也会把所有var变量创建,默认值为undefined,以提高程序的执行效率。也就是说上面的一段代码其实被JS引擎预编译为这样的形式:
var Hello = function() {
    alert("Hello");
}
Hello = function() {
    alert("Hello World");
}
Hello();
Hello();


我们可以通过上面的代码很清晰地看到,其实函数也是数据,也是变量,我们也可以对“函数“进行赋值(重赋值)。

当JavaScript引擎解析脚本时,它会在预编译期对所有声明的变量和函数进行处理。
做如下处理:
1. 在执行前会进行类似“预编译”的操作:首先会创建一个当前执行环境下的活动对象,并将那些用var申明的变量设置为活动对象的属性,但是此时这些变量的赋值都是undefined,并将那些以function定义的函数也添加为活动对象的属性,而且它们的值正是函数的定义
2. 在解释执行阶段,遇到变量需要解析时,会首先从当前执行环境的活动对象中查找,如果没有找到而且该执行环境的拥有者有prototype属性时则会从prototype链中查找,否则将会按照作用域链查找。遇到var a = ...这样的语句时会给相应的变量进行赋值(注意:变量的赋值是在解释执行阶段完成的,如果在这之前使用变量,它的值会是undefined)
所以,就会出现当JavaScript解释器执行下面脚本时不会报错:
alert(a);    // 返回值undefined
var a =1;
alert(a);    // 返回值1

由于变量声明是在预编译期被处理的,所以在执行期间对于所有代码来说,都是可见的。但是,你也会看到,执行上面代码,提示的值是undefined,而不是1。这是因为,变量初始化过程发生在执行期,而不是预编译期。在执行期,JavaScript解释器是按着代码先后顺序进行解析的,如果在前面代码行中没有为变量赋值,则JavaScript解释器会使用默认值undefined。由于在第二行中为变量a赋值了,所以在第三行代码中会提示变量a的值为1,而不是undefined。
分享到:
评论

相关推荐

    javascript预编译思考

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

    JavaScript的执行过程详细研究

    #### 四、预编译与执行顺序 JavaScript在执行之前会经历一个预编译阶段。预编译的主要目的是提升程序的执行效率。在这个阶段,JavaScript引擎会处理函数声明和变量声明,提前创建相应的函数对象和变量对象,并将...

    网站的预编译

    5. **版本控制**:预编译有利于版本控制,因为预编译后的文件与源码分开管理,可以更容易地比较和回滚不同版本的静态资源。 在预编译过程中,通常会涉及到以下技术: - **模板引擎**:例如Jinja2、ERB或Razor,...

    JavaScript作用域原理(二) 预编译[9 29]

    JavaScript中的预编译,也称为提升(Hoisting),是解释器在执行代码之前进行的一种行为。它会将所有的变量声明(`var`关键字)和函数声明(但不包括赋值或表达式)移动到它们所在作用域的顶部。这意味着,即使在...

    JavaScript执行顺序

    JavaScript的执行顺序主要涉及到三个关键点:HTML文档流顺序、预编译与执行顺序的关系以及按块执行JavaScript代码。理解这些概念对于编写高效且无错的JavaScript代码至关重要。 首先,HTML文档流顺序决定了嵌入在...

    JavaScript运行过程中的“预编译阶段”和“执行阶段”

    预编译>执行),了解javascript引擎的执行机理,将有助于在写js代码过程中的思路总结 首先科普下javascript中的两种声明方式,var和function,前者声明的是变量,后者声明的是方法 在预编译中,javascript对这两种...

    javascript编译工具

    结合CSS预处理器如Sass或Less,JavaScript编译工具还能帮助我们将预处理器的代码转换为浏览器可识别的CSS,简化样式编写,并实现模块化管理。 总之,JavaScript编译工具是提升JavaScript开发效率的关键,它们提供了...

    JavaScript 详解预编译原理

    大家要明白,这个预编译和传统的编译是不一样的(可以理解js预编译为特殊的编译过程) JavaScript是解释型语言, 既然是解释型语言,就是编译一行,执行一行 传统的编译会经历很多步骤,分词、解析、代码生成...

    实例讲解JavaScript预编译流程

    在深入理解JavaScript预编译流程之前,我们首先需要明确JavaScript是一种解释型语言,也就是说它会在代码执行时才进行编译。通常情况下,人们会误以为“预编译”这个概念仅适用于编译型语言,但实际上JavaScript引擎...

    JavaScript编译工具

    8. **自动化工作流**:通过与构建工具如Gulp、Grunt或现代的Webpack结合,JavaScript编译工具可以无缝地融入开发者的构建流程,自动处理代码的编译、压缩和版本控制。 总的来说,JavaScript编译工具是现代Web开发中...

    gyp.rar v8库,用预编译v8

    7. 编译完成后,你可以将预编译的V8库集成到你的项目中,享受快速的JavaScript执行性能。 这个过程可能因具体项目需求而略有不同,但总体而言,gyp.rar文件提供了一个跨平台的方式来预编译V8,这对于在多个平台上...

    浅析JavaScript预编译和暗示全局变量

    // 若不执行函数,则不会进行函数预编译,d 就不会提升为全局变量 console.log(c); // error: c is not defined console.log(d); // 4 2. JavaScript执行过程 1. 语法分析,若存在低级语法错误,

    js笔记,预编译/原型/

    预编译是JavaScript引擎在代码执行前进行的一种优化过程,主要涉及到函数声明和变量声明的提升。在JavaScript中,函数声明和变量声明都会被提升到它们所在的作用域顶部,但要注意的是,赋值操作并不会被提升。 1. *...

    JavaScript 语言在引擎级别的执行过程--周爱民

    总的来说,JavaScript在引擎级别的执行过程涉及到了复杂的解析、编译和执行步骤,以及高效的内存管理和异步模型。开发者了解这些知识,不仅可以写出更优的代码,还能对调试和优化问题提供有力的支持。

    javascript v8执行引擎源码

    V8引擎的设计目标是将JavaScript代码直接编译为机器码,从而实现快速执行。它不仅被用在Chrome浏览器上,还被许多其他项目,如Node.js,采用以提供服务器端的JavaScript运行环境。 1. **即时编译(JIT)技术** V8...

    javascript运行机制之执行顺序理解

    JavaScript的运行机制主要涉及到代码块、函数声明与赋值、预编译期和执行期等核心概念。首先,我们从代码块开始。 1. **代码块**:在JavaScript中,代码块通常指的是由`<script>`标签包裹的代码段。每个`<script>`...

Global site tag (gtag.js) - Google Analytics