JS运行三部曲(预编译)

JS运行的三个步骤:

  1. 语法分析
  2. 预编译
  3. 解释执行

语法分析:通俗来说就是通篇检查你的代码有没有语法错误,有语法错误的话,程序是不会执行的

解释执行:也就是程序读一句执行一句

最重点的也就是预编译了,那么预编译到底是什么?它发什么在什么时候?

先来段代码压压惊

function fn (a) {
    console.log(a)
    var a = 123;
    console.log(a)
    function a () {}
    console.log(a)
    console.log(b);
    var b = function () {}
    console.log(b);
    function d () {}
    console.log(d)
}
fn(1)

这是打印结果

ƒ a() {}
123
123
undefined
ƒ () {}
ƒ d() {}

是不是有些地方有点懵逼和意外,其实这就是预编译捣的鬼,预编译就是在函数执行之前,在你的内存中申请一点空间,存放变量和函数
下面说说预编译到底是怎样的过程,也就是上面函数到底发生了什么

预编译过程:

  1. 创建AO对象(Active Object)
  2. 找形参和变量声明,将形参和变量声明作为AO对象的属性名,值为undefined
  3. 将实参与形参统一(把实参值赋予形参)
  4. 在函数体里找函数声明,把函数声明也作为AO对象的属性名,值为函数体()

上面那段代码,fn函数执行之前,先发生预编译过程

第一步

AO = { }

第二步

AO = {
      a:undefined,
      b:undefined
}

第三步

AO = {
      a:1,
      b:undefined
}

第四步

AO = {
      a:function (){},
      b:undefined,
      d:function (){}
}

第四步代表预编译完成,然后函数执行

AO = {
      a:123,
      b:function (){},
      d:function (){}
}
function fn (a) {
    console.log(a)            //这时函数未执行,打印function a(){}
    var a = 123;            //此时执行了a=123
    console.log(a)            //打印123
    function a() {}
    console.log(a)            //打印123
    console.log(b);            //此时函数未执行,打印undefined
    var b = function () {}
    console.log(b);            //此时执行了 b=function(){},打印function(){}
    function d () {}
    console.log(d)            //打印function d(){}}
}
fn(1)

举几个‘栗子’

//1.
function fn(a,b) {
console.log(a);   //打印1
    c = 0;
    var c;
console.log(b);   //打印function b() {}
    a = 3;
    b = 2;
    console.log(b);    //打印2
    function b() {};
    function d() {};
    console.log(b)     //打印2
}
fn(1);
//2.
console.log(bar());      //打印function foo() { //body }
function bar(a,b) {
    return foo;
    foo = 10;
    function foo(){
          //body
    }
    var foo = 11;
}
//3.
console.log(bar());      //打印11
function bar(a,b) {
    foo = 10;
    function foo(){
        //body
    }
    var foo = 11;
    return foo;
   }

以上是单个函数发生的预编译和函数执行过程,那么在<script></script>整个脚本中,是怎么样的呢?

<script type="text/javascript">
  var a = 1;
  function b () {
  var x = 3;
  function d () {}
  }
  var c = function () {
    var y = 4;
  }
</script>

同样的过程,在语法分析之后,开始预编译,不过此时预编译创建的叫GO对象,(Global Object)

GO/window = {
a:undefined,
c:undefined,
b:function b () {
      var x = 3;
      function d () {}
          }
}

函数执行:

GO/window = {
a: 1,
c: function () {  var y = 4;  },
b: function b () {
var x = 3;
function d () {}
            }
}

在执行b函数之前,将b函数预编译,也就是创建b函数的AO对象
如果有两个<script></script>呢?那就先执行完一个,再执行下一个。

注意问题:
预编译只有变量声明、函数声明,并不会发生赋值,赋值发生在执行阶段
匿名函数function (){ } 不参与预编译

原文地址:https://www.cnblogs.com/jiahuasir/p/10571349.html

时间: 2024-10-08 15:22:37

JS运行三部曲(预编译)的相关文章

实例讲解js中的预编译

js作为一本脚本语言,可以不经过编译直接运行,但遇到预编译的问题,尤其是变量或函数同名时,这点知识就尤其必要了.为了更好地了解js语言背后的运行机理.笔者采用实例化的方式讲解我理解的预编译.    理解预编译首先要弄清楚两种概念:函数声明和变量赋值. function ledi(){ }//函数声明 这种形式的写法是函数声明,即声明一个函数,脚本在执行之前会做预编译处理. var ledi= function(){ }//变量赋值   这种写法是变量赋值,函数在js语言里也是一种数据,匿名函数作

js - 基础 之 预编译总结

js运行步骤 语法解析(检查有无语法错误) 预编译 解释运行(将 js 翻译成计算机识别的语言(0.1组成),翻译一行执行一行) 预编译 [全局]: 创建 GO( Grobal Object ) 对象 找变量声明 找函数声明 [函数]: 创建 AO( Activation Object ) 对象(执行上下文): 找形参和变量声明,将形参和变量名作为 AO 对象的属性名,值为 undefined(有重复的名称只写一个即可): 将形参与实参值统一(用实参的值替换 undefined): 在函数体中找

JS作用域和预编译(转载 学习中。。。)

JS在页面加载过程中顺序执行.但是分块预编译.执行. JS在执行前会进行类似”预编译”的操作,而且先预声明变量再预定义函数. 此时注意,是声明,不是定义,如:var a = 1; 在预编译中,只是执行了”var a”没有赋值,即在预编译结束时a 为undefined. (注意)并不是先全文编译完在执行,而是块编译,即一个script块中,预编译再执行,然后(按顺序)下一个script块,预编译再执行,但此时上一个块中的数据都是可以用的,但下一个块中的函数,声明的变量都是不可用的. 变量没声明就引

JS中的预编译(词法分析)阶段和执行阶段

javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段,而在javascript中也有类似的“预编译阶段”(javascript的预编译是以代码块为范围<script></script>,即每遇到一个代码块都会进行  预编译>执行),了解javascript引擎的执行机理,将有助于在写js代码过程中的思路总结 首先科普下javascript中的两种声明方式,var和function,前者声明的是变量,后者声明的是方法 在预

gulp最佳实践(包含js,css,html预编译,合并,压缩,浏览器自动刷新)

gulp是基于流的自动化构建工具官方网址:http://www.gulpjs.com.cn/ 一.安装需要的模块 1.新建package.json,输入下面的内容 { "name": "autopractice", "version": "1.0.0", "description": "", "main": "index.js", "sc

JS的预编译和执行顺序 详析

原文:JS的预编译和执行顺序 详析 最近在复习javascript的事件处理时发现了一个问题,然后也是我来写javascript的预编译和执行顺序的问题   代码:   复制代码 代码一 <html>   <head>     <title>事件处理</title>     <meta http-equiv="content-type" content="text/html;charset=utf-8"/>

JS的预编译和执行顺序 详析(及全局与局部变量)

最近在复习javascript的事件处理时发现了一个问题,于是总结一下:javascript的预编译和执行顺序的问题:   <html> <head> <title>事件处理</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> <script type='text/javascript'> //页

Rails : css或js文件无法成功预编译或调用jquery类插件时预编译问题

调用bootstrap css框架时,将bootstrap文件夹放入 vendor/assets/下 bootstrap文件结构如下:    [[email protected] demo]$ ls vendor/assets/bootstrap/     css  img  js [[email protected] demo]$ ls vendor/assets/bootstrap/css/     bootstrap.css  bootstrap.min.css  bootstrap-re

JavaScript 之 预编译 作用域,作用域链

第一次写博客,本来是学习jQuery遇到闭包问题,发现并没有理解闭包,发现闭包牵扯的知识点太多.复习了一遍(发现自己该记住的全忘了)写在博客里,自己也是小白,希望大神们指点迷津,必将感激不尽. 我们知道JavaScript有两个特点:单线程,解释型语(翻译一行,解释一行).但其实翻译一行,解释一行是最后一部才这样做,在这之前会有一个语法分析:通篇扫描看有没有语法错误,但不执行,通篇扫描之后,会进行 预编译 然后 -->解释一行,执行一行.这就是我们所说的js运行三部曲:语法分析     预编译