首先要理解什么是预编译:

  预编译就是在JS执行前的一瞬间创建一个AO对象,这个创建AO的过程叫做预编译。

console.log(a)
var a = 1;
function c(b){
b = 10;
console.log(b);
console.log(a);
var a = function(){};
function a(){};
}
c(5);

借助上述代码中:

  可以将预编译分为四步:

  1.执行前一瞬间建立AO对象:

    AO{

      a:undefined

      b:undefined

    }

  首先所有变量都是undefined状态,

  2.分析函数,将实参作为相应形参的值

    AO{

      a:undefined

      b:5

    }

  3.在函数中找到函数体,并赋值,并且找到变量声明,也为其赋值;

  AO:{

    a: function a(){};

    b:10

  }

  4.执行函数

    输出结果为:

  undefined

  10

  ƒ a(){}

但是在预编译中,还有一个GO对象,他在函数体之前,和AO不同,他包含所有的全局变量以及函数名

a = 20;
console.log(a);
function z(){
console.log(a)
}
z();

从上图中可以看到,GO和AO的执行区别,GO会将函数体的所有全局变量以及函数名收纳着

接下来谈谈作用域链

  了解作用域链之前,先说作用域。作用域就是代码的执行环境,

  1.全局作用域:

  最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的:

  2.局部作用域: 

  和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,在这里要强调一点,在声明变量时一定要使用var之类的关键字,不然就成了全局变量。

  当代码在一个环境中执行的时候就会形成变量对象的一个作用域链,一个作用域中的对象会通过在相同环境中形成的作用域链条找到下一个对象,依次寻找,一直找到全局环境,作用域链是环环相扣的。

  作用域链就是变量之间的关系链一样,当然,不同的环境有不同的作用域。在内部函数中,需要访问一个变量的时候,首先会访问这个函数本身的变量对象,检测是否包含这个变量,如果没找到就会继续沿作用域链向上查找,直到全局作用域。如果在某个变量对象中找到则使用该变量对象中的变量值。

上图函数的执行过程:

  开始执行---生成栈 --- 执行结束  ---  销毁----出栈

全局对象:a1  fun1

fun1 的变量对象:a2 fun2

fun2 的变量对象: a3

以上就是对预编译以及作用域和作用域链的理解。

预编译And作用域链的更多相关文章

  1. JavaScript 预编译与作用域

    JavaScript 预编译与作用域 JavaScript 预编译的过程和作用域的分析步骤是 JS 学习中重要的一环,能够帮助我们知道代码的执行顺序,更好理解闭包的概念 预编译 JavaScript ...

  2. 预编译语句(Prepared Statements)介绍,以MySQL为例

    背景 本文重点讲述MySQL中的预编译语句并从MySQL的Connector/J源码出发讲述其在Java语言中相关使用. 注意:文中的描述与结论基于MySQL 5.7.16以及Connect/J 5. ...

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

    第一次写博客,本来是学习jQuery遇到闭包问题,发现并没有理解闭包,发现闭包牵扯的知识点太多.复习了一遍(发现自己该记住的全忘了)写在博客里,自己也是小白,希望大神们指点迷津,必将感激不尽. 我们知 ...

  4. js隐式类型转换,预编译、递归、作用域,作用域链、闭包、立即执行函数、继承圣杯模式

    隐式类型转换 调用Number()当有运算符(加减乘除,求余)时,会调用Number()转为数字再运算,除了 加 当 有字符串时就变身成拼接Boolean();String(); typeof()st ...

  5. js作用域链和预编译

    js引擎运行分为两步,预解析 代码执行 (1)预解析: js引擎会拿js里面所有的var还有 function 提升到当前作用域的最前面 (2)代码执行:按照代码书写的顺序从上往下执行 预解析分为:变 ...

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

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

  7. JavaScript作用域及预编译

    几乎所有的编程语言都可以存储,访问,修改变量,那在JavaScript中这些变量放在那里?程序如何找到他们? js被归类于解释执行语言,但事实上他也是一门编译语言,因为他也要编译,但于传统的编译语言不 ...

  8. JS笔记--------预编译,闭包和作用域

    (一)JS预编译四部曲: 1,创建AO对象. 2,找形参和变量声明,将变量和新参名作为AO属性名,值为undefined. 3,将实参值和形参值统一. 4,在函数体里找函数声明,值赋给函数体. (二) ...

  9. Javascript - 预编译与函数词法作用域

    预编译与函数词法作用域(Precompiled & Scoped) 预编译 Javascript脚本的宿主在执行代码之前对脚本做了预编译处理,比如浏览器对Js进行了预编译,编译器会扫描所有的声 ...

随机推荐

  1. Flutter 目录结构介绍、入口、自定义 Widget、MaterialApp 组件、Scaffold 组件

    Flutter 目录结构介绍 文件夹 作用 android android 平台相关代码 ios ios 平台相关代码 lib flutter 相关代码,我们主要编写的代 码就在这个文件夹 test ...

  2. oracle11g 查询临时表空间的使用率和正在使用临时表空间的用户

    转: oracle11g 查询临时表空间的使用率和正在使用临时表空间的用户 原创 Oracle 作者:记录每一次错误 时间:2018-12-21 15:46:33 11179 0 今天开发反映说临时表 ...

  3. Qt QLabel加载图片

    QLabel加载图片 //在对应的控件中显示图片 void qm_img::DisplayImg(cv::Mat imgParam, QLabel *labelParam) { if (!imgPar ...

  4. github上fork分支后再合入原master分支的改动

    几个月前看到一个电商项目,文档比较全,fork下来学习下.后来因为其他事情耽搁了,现在想重新看看,发现改动比较大,master分支跟我fork下来的分支不一样了.咋办?简单,把最新的master分支下 ...

  5. 修复gitlab服务器突然停电导致PostgreSQL损坏的数据库

    最开始是存储的卷组受损,使用的DRBD,使用了xfs分区格式: 挂载也报错: mount /dev/drbd0 /var/opt mount: wrong fs type, bad option, b ...

  6. Spring cloud微服务安全实战-5-1单点登录基本架

    基于微服务架构,前后端分离实现SSO 前后端分离到底是个什么样的架构. 中间不是用Nginx而是用Node JS. node.js在服务端的页面渲染,这样搜索引擎爬虫 来爬的时候 爬的就是html页面 ...

  7. Qt编写控件属性设计器12-用户属性

    一.前言 用户属性是后面新增加的一个功能,自定义控件如果采用的Q_PROPERTY修饰的属性,会自动识别到属性栏中,这个一般称为控件属性,在组态设计软件中,光有控件本身的控件属性还是不够的,毕竟这些属 ...

  8. 123457123456#0#-----com.cym.shuXue02--前拼后广--开心学数学

    com.cym.shuXue02--前拼后广--开心学数学

  9. 深入理解JVM+G1+GC.pdf (中文版带书签)

    目录 序 VII前言 IX 第1章 JVM & GC基础知识 11.1 引言 21.2 基本术语 31.2.1 Java相关术语 41.2.2 JVM/GC通用术语 241.2.3 G1涉及术 ...

  10. LwIP应用开发笔记之一:LwIP无操作系统基本移植

    现在,TCP/IP协议的应用无处不在.随着物联网的火爆,嵌入式领域使用TCP/IP协议进行通讯也越来越广泛.在我们的相关产品中,也都有应用,所以我们结合应用实际对相关应用作相应的总结. 1.技术准备 ...