首先要记住:预编译发生在函数执行的前一刻

先来一个小知识:

  1. 函数声明整体提升
test();
function test(){...//省略n行代码
}

在预编译阶段,会把函数声明提升到代码顶部:

function test(){....
}
test();
  1. 变量声明提升
console.log(a);
var a=123;

在预编译阶段,会把var声明提升到代码段的顶端:

var a;
console.log(a);
a=123;

控制台输出 undefined

但上面两点在遇到下面这种情况时就不够用了

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() {}
}
fn(1);

接下来就是预编译表演的时刻了:

  1. 创建AO(Activation Object----活跃对象)对象(另一个名称叫执行期上下文)
AO{}
  1. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
AO{a:undefind,//形参和变量重名时,不需要重复创建b:undefind
}
  1. 将实参值和形参统一
AO{a:1,b:undefind
}
  1. 在函数体里找函数声明,函数名为AO属性名,值为函数体
AO{a:function a() {},//当函数名重名时,不需要重复创建,直接赋值即可b:undefind,d:function () {}
}

原函数变为(忽略变量声明与函数声明):

function fn(a){console.log(a);//从AO中取a的值为function a() {}a=123;//把123赋给给AO中的aconsole.log(a);//此时a为123console.log(a);//还是123b=function () {}//把函数体赋给AO中的bconsole.log(b)//function b() {}function d() {}
}
fn(1);

再来一个例子

function test(a,b){console.log(a);c=0;var c;a=3;b=2;console.log(b);function b() {}function d() {}console.log(b);
}
test(1);
  1. 创建AO对象
AO{}
  1. 找形参和变量声明,将变量和形参名作为AO属性名,值为 undefined
AO{a:undefind,b:undefind,c:undefind
}
  1. 将实参值和形参统一
AO{a:1,b:undefind,c:undefind
}
  1. 在函数体里找函数声明,函数名为AO属性名,值为函数体
AO{a:1,b:function b() {},c:undefind,d:function d() {}
}

原函数变为(忽略变量声明与函数声明):

function test(a,b){console.log(a);//AO中a的值为1c=0;//0赋给AO中的ca=3;//3赋给AO中的ab=2;//2赋给AO中的bconsole.log(b);//AO中b的值为2console.log(b);//2
}
test(1);

练习:

function test(a,b){console.log(a);console.log(b);var b=234;console.log(b);a=123;console.log(a);function a() {}var a;b=345;var b=function b() {}console.log(a);console.log(b);
}
test(1);
AO{a:function a() {},b:undefind
}

(忽略变量声明与函数声明)

function test(a,b){console.log(a);//function a() {}console.log(b);//undefindb=234;console.log(b);//234a=123;console.log(a);//123b=345;b=function b() {}console.log(a);//123console.log(b);//function b() {}
}
test(1);

上面只是讲述在函数中的预编译,接下来加入全局的,中间插播一段作用域的小知识

  1. 一切声明的全局变量,都是 window 的属性
 var a = 3;   ===>   window.a = 3;
  1. 所有未经声明就赋值的变量都是全局变量
 1. a=3;2. var a = b = 3;//b未声明就赋值

回到我们的预编译

var a=123;
function a() {var a=b=3;
}
a();
  1. 生成一个GO(Global Object---全局对象)对象
GO{a:123,b=3;//未经声明的变量赋值为全局变量
}
GO ===> window
  1. 执行a(),生成AO对象

让我们来熟悉一下全局对象

var a=100;
function fn() {console.log(a);
}
fn();
  1. 生成GO
GO{a:100,fn:function fn() {}
}
  1. 执行fn()前一刻生成AO对象
AO{}
  1. 执行fn()
首先在自己的AO中找a属性
AO{}AO中没有,去上一级GO中找
GO{a:100,fn:function fn() {}
}找到a,控制台打印100

举个栗子:

console.log(test);
function test(test){console.log(test);var test=234;console.log(test);function test() {}
}
test(1);
var test =123;
  1. 生成GO,生成的过程步骤与AO一样
GO{test:function test() {}
}
console.log(test);//function test() {}
function test(test){...
}
test(1);
var test =123;
  1. 执行到test(1)前一刻,生成AO
AO{test:function test() {}
}
  1. 执行test(1)(忽略变量声明与函数声明)
function test(test){console.log(test);//首先会在自己的AO中找是否有test属性,有就用自己的,没有就去GO中找,此时AO中有test,值为function test() {}test=234;console.log(test);//234
}

以上为本人观看成哥javascript视频教程后对预编译的总结,如有错误请指出。

转载于:https://juejin.im/post/5b0f5edc6fb9a00a0c372c1b

javascript之预编译相关推荐

  1. JavaScript的预编译及执行顺序

    从JavaScript引擎的解析机制来探索JavaScript的工作原理,下面我们以更形象的示例来说明JavaScript代码在页面中的执行顺序. 如果说,JavaScript引擎的工作机制比较深奥是 ...

  2. Javascript作用域原理---预编译

    问题的提出 首先看一个例子: var name = 'laruence'; function echo() { alert(name); var name = 'eve'; alert(name); ...

  3. javascript运行过程中的“预编译阶段”和“执行阶段”

    javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段 而在javascript中也有类似的"预编译阶段"(javascrip ...

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

    javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段,而在javascript中也有类似的"预编译阶段"(javascrip ...

  5. 5单个编译总会编译全部_5分钟读懂JavaScript预编译

    大家都知道JavaScript是解释型语言,既然是解释型语言,就是编译一行,执行一行,那又何来预编译一说呢?脚本执行js引擎都做了什么呢?今天我们就来看看吧. 1-JavaScript运行三部曲 语法 ...

  6. JavaScript作用域原理——预编译

    JavaScript是一种脚本语言, 它的执行过程, 是一种翻译执行的过程.并且JavaScript是有预编译过程的,在执行每一段脚本代码之前, 都会首先处理var关键字和function定义式(函数 ...

  7. javascript代码块概念及预编译机制

    JavaScript是一种描述型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行.如果你不能理解javaScript语言的运行机制,或者简单地 ...

  8. JavaScript预编译

    前言:在JavaScript中存在一种预编译的机制,这也是Java等一些语言中没有的特性,也就正是因为这个预编译的机制,导致了js中变量提升的一些问题,下面这两句话能解决开发当中一部份问题,但不能解决 ...

  9. JavaScript预编译过程

    JavaScript预编译过程 阶段(三个) 预编译过程 1. JavaScript代码执行之前的预编译 案例说明 2. 函数执行前的预编译 案例说明 总结 预编译两个小规则: 预编译前奏 阶段(三个 ...

最新文章

  1. python的httplib、urllib和urllib2的区别及应用
  2. 【Linux】X window与文本模式的切换
  3. 2020计算机应用模拟题,2020年函授本科计算机应用基础课后作业、模拟题及答案...
  4. Vm虚拟化连不上存储服务器,VMware服务器虚拟化、虚拟桌面应该选择什么存储品牌最好--我们有软硬方案...
  5. Android短信拦截代码
  6. ABP实战--集成Ladp/AD认证
  7. 企业实施WMS仓储管理系统需要规避哪些风险
  8. 电影后期制作图形服务器,影视后期制作中存储的选择——MDC服务器篇
  9. 数字化时代,企业应该如何看待商业智能BI
  10. Java中遍历Map集合的5种方式总结
  11. 搜狗壁纸停运了,但我还是想推荐它……(附个人的一点想法)
  12. 五金机电行业S2B2B商城系统打破传统线下营销方式,实现企业高质量发展
  13. 金融网站知识图谱问答系统:自学Python第一周
  14. 基于Cesium的指南针插件
  15. SAP 批次管理(批次层级--异常处理)
  16. 组件 {B31118B2-1F49-48E5-B6F5-BC21CAEC56FB} 的事件解决方法
  17. 发那科机器人示教器电缆线_详解发那科机器人安装步骤
  18. java tire树_Java实现Tire
  19. 5G网关如何赋能智慧油井监测?油井管理如何迈上新台阶
  20. 在linux环境中将Excel转换成文本

热门文章

  1. OpenCV 中文wiki
  2. 线程间的通信方式1--共享变量(内存)
  3. 登录centos虚拟机后显示-bash-4.1
  4. 深入浅出Attribute (转载)
  5. 在Win平台得到磁盘、CPU、用户信息
  6. Navicat 10 for SQL Server - 绿色中文版
  7. DISCUZ中判断当前页是否是门户首页
  8. 我的学习之路_第二章_接口/多态
  9. 最近关于less sass的新手总结
  10. TCP/IP协议各层首部汇总