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

  预编译就是在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. Spring cloud微服务安全实战-6-6jwt改造之日志及错误处理(2)

    第一次请求失败了 打印出了403,第二次更新成功 现在只处理了403这种情况,还有一种情况就是401,就是当前用户需要做身份认证,你没有做身份认证. 401的处理 与403类似,也是在这里配置.Ent ...

  2. 【Mac】解决外接显示器时无法用键盘调节音量

    背景:mac book pro  外接一台显示器 可以有音量,音量较小, 外接两台显示器时候直接显示如下了 解决办法: 操作步骤: 从 GitHub 下载 SoundFlower 扩展,并安装.(首次 ...

  3. quasar 报错

    yarn是项目建议安装的方式,报错如下 npm 安装的项目,报错如下 情况:无论是哪种安装方式,似乎报错都出在同一个地方. 近况,还在解决中...

  4. 123457123456#2#----com.MC.ShiZi365--前拼后广--儿童识字Game-mc22222222222222222

    com.MC.ShiZi365--前拼后广--儿童识字Game-mc

  5. 123457123456#1#----com.tym.DishuGame78--前拼后广--宝宝打地鼠_tym

    com.tym.DishuGame78--前拼后广--宝宝打地鼠_tym

  6. LeetCode_371. Sum of Two Integers

    371. Sum of Two Integers Easy Calculate the sum of two integers a and b, but you are not allowed to ...

  7. PhpStorm (强大的PHP开发环境)10.0.2 附注

    最新版PhpStorm 10正式版改进了PHP 7支持,改进代码完成功能. PhpStorm 是最好的PHP开发工具,使用它进行PHP开发将会让你感觉到编程的乐趣. 快乐无极终于从oschina看到了 ...

  8. left join 和inner join关联查询区别

    inner join 必须两边对应才能查处结果 left join 用主表关联副表,关联不出来依然显示结果

  9. [转帖]Docker Hub上镜像发现挖矿蠕虫病毒,已导致2000台主机感染

    Docker Hub上镜像发现挖矿蠕虫病毒,已导致2000台主机感染 https://www.kubernetes.org.cn/5951.html 本来想说可以用 official版本的镜像 但是一 ...

  10. 构建工具-Gulp 相关知识

    layout: layout title: 『构建工具-Gulp』相关内容整理 date: 2017-04-26 22:15:46 tags: Gulp categories: Tools --- G ...