美文网首页
JavaScript预编译和变量提升

JavaScript预编译和变量提升

作者: 椰果粒 | 来源:发表于2019-03-15 16:43 被阅读0次

JavaScript是解释型语言,会先预编译,然后执行,在执行过程中顺序执行。
因此在JS中存在变量提升的现象

在函数中预编译执行步骤:

  • 创建空AO对象,(Activity Object)执行期上下文
  • 寻找函数的形参变量声明,将变量和形参作为AO对象的属性名,值为undefined
  • 将形参和实参相统一,将undefined更改为具体实参值。
  • 寻找函数中的函数声明,将函数名作为AO属性名,值为函数体
  • 预编译环节结束
  • 执行,不断更新AO对象
  • 执行完毕,AO对象销毁

全局对象GO也是一样

实例一

function fn(a){
  console.log(a)
  var a = 123
  console.log(a)
  function a(){}
  console.log(a)
  var b = function(){}
  console.log(b)
  function d(){}
}
  1. 创建空AO对象
AO{
  // 空对象
}
  1. 寻找函数形参和变量声明
AO{
  a: undefined,
  b: undefined,
}
  1. 将形参和实参相统一
AO{
  a: 1,
  b: undefined
}
  1. 函数声明
AO{
  a: function a(){},
  b: undefined,
  d: function d(){},
}

预编译环节结束,AO对象更新为

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

函数开始顺序执行

function fn(a){
  console.log(a); // function a(){}
  var a = 123     // 对a赋值,AO对象改变
  console.log(a)  // 123
  function a(){}  // 预编译环节进行变量提升,执行时不看此行代码
  console.log(a)  // 123
  var b = function(){}  // 函数声明,对b重新赋值,AO对象改变
  console.log(b)   // function b(){}
  function d(){}  // 预编译环节变量提升,执行时不再看此行代码
}

实例二

function test(a,b){
  console.log(a); // 1
  c = 0;          // AO更新
  var c;          // 预编译,不看
  a = 3;          // AO更新
  b = 2;          // AO更新
  console.log(b); // 2
  function b(){}; // 预编译,不看
  function d(){}; // 预编译,不看
  console.log(b); // 2
} 
test(1); // 1 2 2
/**
AO1{}
AO2{
  a: undefined,
  b: undefined,
  c: undefined,
}
AO3{
  a: 1,
  b: undefined,
  c: undefined,
}
AO4{
  a: 1,
  b: function a(){},
  c: undefined,
  d: function c(){},
}
end;
**/

实例三

// 引入GO(全局对象)
console.log(test);    // function test(test){,,,,,}
function test(test){
  console.log(test);  // function test(){}
  var test = 234;     // AO改变
  console.log(test);  // 234
  function test(){}   // 预编译,不看
}
test(1);
var test = 123;

执行结果:
// function test(test){,,,,,}
// function test(){}
// 234

解析过程:
/**
页面加载完成,生成GO对象 
GO1{
  test: undefined
}
GO2{
  test: function(test){xxxxx}
}
执行test()钱生成AO对象
AO1{
  test: undefined,
}
AO2{
  test: 1
}
AO3{
  test: function test(){}
}
预编译结束,开始执行
AO4{
  test: 234
}
**/

实例四

function demo(){
  console.log(b);  // undefined
  if(a){
    var b = 100;
  }
  console.log(b);  // undefined
  c = 234;         // 全局变量
  console.log(c);  // 234
}
var a;
demo();
a = 10;
console.logs(c);   // 234

// undefined undefined 234 234

/* 
GO1{
  a: undefined
}
GO2{
  a: undefined,
  demo: function demo(){xxxxx},
}
执行demo函数前预编译,由于c未声明就使用,所以是全局变量
GO2{
  a: undefined,
  demo: function demo(){xxxxx},
  c: undefined
}
a是undefined,if里不执行
输出undefined
GO4{
    a : undefined,
    demo : function demo(){}
    c : 234;
}
//输出234
GO5{
    a : 10,
    demo : function demo(){}
    c : 234;
}
//输出234
*/

本文参考https://juejin.im/post/5aa6693df265da23884cb571

相关文章

  • JavaScript预编译和变量提升

    JavaScript是解释型语言,会先预编译,然后执行,在执行过程中顺序执行。因此在JS中存在变量提升的现象 在函...

  • 如何理解javascript变量提升

    记住以下两点会对了解javascript有帮助: 变量提升 javascript引擎在编译js代码的时候会先将变量...

  • javascript变量提升

    预解释,又叫做变量提升,是指在javascript运行前,对变量进行提前声明,要注意的点是带var关键字和func...

  • 2019-05-11

    JavaScript 预编译:函数声明提升,变量声明提升 2018年06月21日 20:45:17 __Amy 阅...

  • 你需要知道的javascript的提升

    javascript在执行前会有一个预编译过程,预编译过程会先预声明变量再预定义函数,比如 预编译过后,类似于 运...

  • JavaScript代码是怎么执行的?

    前言 众所周知,JavaScript是单线程语言。所以JavaScript是按顺序执行的! 先编译再执行 变量提升...

  • javascript中的 预编译

    JavaScript运行三部曲 语法分析 预编译-函数声明 整体提升-变量 声明提升 解释执行 暗示全局变量:即任...

  • 变量提升(mdn自学)

    变量提升是变量和函数的声明编译阶段被放入内存中JavaScript 在执行任何代码段之前,将函数声明放入内存中的优...

  • 一些面试题的编程题技巧及更好的理解函数作用域和变量提升(ES5)

    注:本文中预解释就是 函数在执行时进行的例如变量提升 一. 在JavaScript中的函数理解中预解释是一个比较...

  • day06(2017.10.9)

    一、变量声明提升 引擎解释javascript代码的之前会对其进行编译。在编译过程中会查找所有声明,并用合适作用域...

网友评论

      本文标题:JavaScript预编译和变量提升

      本文链接:https://www.haomeiwen.com/subject/usrrmqtx.html