前置知识:需理解JS的执行上下文概念。

理解执行上下文前,先理解什么是执行。

假如整个程序只有一行代码,能否执行?

如果这一行代码是一个函数声明,这个程序不会执行,而且也没有生成执行上下文对象。连全局上下文对象也没有。

顺便引申出,如果在一个A函数里,再申明一个B函数,只有这一个声明语句的话,这个B函数也不会保存在A函数的执行上下文里。

在这里,可以得出一个基本结论,在全局作用域和局部作用域里,函数声明是不可执行的语句

当有了可执行的代码,程序才会真正执行,并且在执行前产生执行上下文。

它是JS引擎虚拟出来的放来存放数据的对象。这个对象无法用代码访问,但是在代码执行过程中却真实存在。执行上下文对象统称为变量对象。

以谷歌浏览器为例:

全局作用域下的变量对象叫:Global Object ,简称GO。

局部作用域下的变量对象叫:Local Object,简称LO。《高级程序设计》一书中称为活动对象叫Activation Object,简称AO。

块作用域下的变量对象叫:Block Object,简称BO。

还有一个ES6后才有变量对象:Script Object,简称SO。SO对象仅仅用来保存在全局作用域下,let和const声明的变量。

先讨论全局作用域和局部作用域下的变量提升,块级作用域的变量提升会有不同的行为。

全局作用域下:

在可执行代码执行前,JS引擎会把变量声明和函数声明保存在GO对象中。GO对象就是全局的执行上下文。

变量声明的两种情况:

第一种使用var 声明变量:使用var声明的变量会被保存到GO对象里,同时widow对象里也存有一模一样的值。其初始值为undefined,在赋值操作前访问打印出来就是undefined。

第二种使用let或者const声明变量:他们声明的变量会保存在SO对象里,初始值也是undefined,但是由于暂时性死区的存在无法在初始化值前访问他们声明的变量。

所以基于以上的区别,从能否在初始化前访问变量的角度来说,只有var声明的变量才有变量提升效果。

但实际上,let和const声明的变量,在程序执行前,同样会保存到上下文对象里。

在局部作用域(也就是函数作用域)下:

函数体里的可执行代码执行前,会生成LO对象(AO对象)用来保存形参,实参传递进来的值,保存内部的变量声明值为undefined和函数声明值为函数本身,还有this的值。这个LO对象就是函数的执行上下文。

局部作用域下,浏览器怪异行为较少,没有太多的补丁感。所以代码实践中,都是先定义函数,在函数里玩各种骚操作。(比如闭包)

在块作用域下:

块作用域下的执行上下文对象叫BO,和其它两个作用域一样,会保存变量声明值为undefined,保存函数声明值为函数本身。里面没有this。

块作用域存在时,块作用域下的函数声明会先保存在GO对象里,且值为undefined。这跟其它两个作用域有重要区别。

执行到块作用域时,块作用域下的函数声明会再次执行(注意:之前我们得出结论是在全局和局部,函数声明不可执行。),且会把BO对象里函数变量名下的值同步给GO对象里的同名变量。

这种浏览器的怪异行为,是为了在ES6时代兼容ES5语法而设计的。

补充:

eval()调用内部存在第三种上下文。

总结:

  1. 只有函数的执行上下文才有this
  2. 多在函数作用域下写代码
  3. 块作用域下,函数声明是可执行语句
  4. 执行上下文是一个对象,用来保存代码执行前的一些初始化值

JavaScript-彻底讲清楚什么是变量提升相关推荐

  1. JavaScript中的预解析(变量提升)介绍!

    今天小千为大家介绍一下JavaScript中的预解析(变量提升).从什么是预解析及变量的预解析和函数的预解析及加载流程进行学习(注意:我们这里说的ES5中的预解析). 什么是解析 首先代码执行肯定需要 ...

  2. JavaScript通俗易懂(一)-变量提升

    原文链接:http://www.jianshu.com/p/330b1505e41d 在JavaScript中,我们肯定不可避免的需要声明变量和函数,可是JS解析器是如何找到这些变量的呢?我们还得对执 ...

  3. 关于JavaScript的词法作用域及变量提升的个人理解

    关于JavaScript的作用域,最近听到一个名词:"词法作用域":以前没有听说过(读书少),记录一下对此的理解,加深印象. 词法作用域:在JavaScript中,一个函数的作用域 ...

  4. JavaScript专题(一)变量提升与预编译,一起去发现Js华丽的暗箱操作

    JavaScript之变量与函数提升 相信阅读完<前端进阶系列>的朋友们已经对Js中经典的知识点有所了解.本系列的第一篇选择了一个值得讨论的问题--变量提升,我们会从遇到问题.分析问题.解 ...

  5. javascript --- js中的作用域 变量提升

    1 求以下函数的输出 1.1 考察点: 变量提升.this.作用域 // 考察点 作用域.this.变量提升 var a = 10 function test() {a = 100console.lo ...

  6. 【Web前端培训】预解析(变量提升)

    今天千锋小编为大家介绍一下一下JavaScript中的预解析(变量提升).从什么是预解析及变量的预解析和函数的预解析及加载流程进行学习(注意:我们这里说的ES5中的预解析). 什么是解析 首先代码执行 ...

  7. JavaScript 笔记(2) -- 类型转换 正则表达 变量提升 表单验证

    目录:  typeof, null, undefined, valueOf() 类型转换 正则表达式 错误: try, catch, throw 调试工具 变量提升 strict 严格模式 使用误区 ...

  8. JavaScript中变量提升是什么?如何实现?

    在进行web前端开发的时候,我们经常会遇到变量提升的情况,那么JS在解析变量的时候是如何做到提升的呢?今天小千就来带大家了解一下. 首先在JS中涉及两种作用域的问题,那么什么是作用域呢? 作用域是代码 ...

  9. JavaScript中函数的变量提升问题

    函数的大体分三种,一种是函数的声明,一种是函数表达式(又称为函数的字面量) 1.函数的声明 => function myFn(){}; 2.函数的表达式 => var myFn = fun ...

最新文章

  1. Driver for device rausb0 has been compiled with version 22
  2. PHP面试题:请说明 PHP 中传值与传引用的区别。什么时候传值什么时候传引用?
  3. 【转】C#字节数组_字符串相互转换
  4. linux 内核宏container_of剖析
  5. Redis经典面试题
  6. matlab编写全置信度函数,Matlab_curve_fitting_tool的用法图文结合
  7. ensp华为数通远程登录配置
  8. html制作凤凰网,有哪些不用编写代码就能轻松制作生成HTML5页面的工具
  9. 基于junit4的关于个人所得税计算的等价类与边界值_微服务的未来——从单体服务角度看微服务与云计算DevOps结合的演进...
  10. 短视频去水印接口支持全网解析源码/自定义API接口
  11. 3dmax推荐用哪个版本,主流好用的版本有哪些?
  12. 生物特征认证和识别市场现状及未来发展趋势
  13. mysql查询前100个_mysql查询前100条数据
  14. 在VS中如何生成moc文件
  15. 推荐几款好看又好用的开源博客
  16. 手把手带你从0完成医疗行业影像图像检测三大经典模型InceptionV3-RestNet50-VGG16(附python源代码及数据库)——改变世界经典人工智能项目实战(一)手把手教学迁移学习
  17. java版捕鱼达人----完整版补充
  18. 怎么mac ftp服务器文件夹,mac 访问 ftp服务器文件夹权限
  19. mini2440 LED 测试
  20. Java图片压缩大小,图片缩放

热门文章

  1. 什么牌子的蓝牙耳机音质最好?四大品牌音质最好的蓝牙耳机推荐
  2. 大一计算机ppt4.3实训内容,沪科教版信息技术七年级下册4.3《图文混排》PPT课件4.ppt...
  3. 空谷助力菲索中国形象升级
  4. 创下多项“首个”的开源玩家 —— VMware 中国研发中心技术总监张海宁
  5. Python将PPT中所有文本框里的文字提取出来
  6. 协同控制笔记1——基础介绍及部分定义定理
  7. 友盟+又双叒叕得奖了!这次是爱分析·数据智能厂商全景报告
  8. Spring-data-jpa最全的查询语法总结,直入超神
  9. 精准营销的前提:精准的市场细分和消费者需求定位
  10. 平面设计需要学习哪些知识和技能?