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

  预编译就是在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. Dart匿名方法函数和闭包

    /* 内置方法/函数: print(); 自定义方法: 自定义方法的基本格式: 返回类型 方法名称(参数1,参数2,...){ 方法体 return 返回值; } */ void printInfo( ...

  2. Python3基础 函数 多值参数 元组与字典形式(键值对分别指出)

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  3. Python3基础 complex real imag __abs__ 取复数的实部 虚部 模

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  4. 004-行为型-01-策略模式(Strategy)

    一.概述 定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户.需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可 ...

  5. Linux的桌面虚拟化技术KVM(四)——虚拟机镜像格式对比与转换

    Linux的桌面虚拟化技术KVM(一)——新建KVM虚拟机 Linux的桌面虚拟化技术KVM(二)——远程桌面管理 Linux的桌面虚拟化技术KVM(三)——KVM虚拟机克隆和快照 (1).常用镜像格 ...

  6. Python - Django - ORM 聚合查询和分组查询

    models.py: from django.db import models # 出版社 class Publisher(models.Model): id = models.AutoField(p ...

  7. LODOP打印table表格宽度固定-超宽隐藏

    之前有博文介绍关于超出div隐藏内容的:LODOP打印超过后隐藏内容样式里面提到了overflow:hidden;控制超出后隐藏,但是前面那篇用的是div,如果是在table中,由于table默认的t ...

  8. 获取本机IP地址[JavaScript / Node.js]

    --web客户端JavaScript <body onload="checkCookie()"></body> function getYourIP(){ ...

  9. union all 关键字的应用(合并两个查询结果集到同一个结果集)

    在此对于数据库中 union all 关键字的功能和用法进行简单的使用介绍. 这是我工作中的一个需求: 有两个 A表 和B表. A表的数据: B表的数据: 现在有这样一个需求,让他一次性的全部查出来. ...

  10. Linux【Ubuntu】安装docker

    内核要大于3.10才能安装docker 查看内核 uname -r 安装yum命令 sudo apt install yum 由于 apt 源使用 HTTPS 以确保软件下载过程中不被篡改,故添加使用 ...