在很多面试题中,经常会看到关于变量提升,还有函数提升的题目,所以我就写一篇自己理解之后的随笔,方便之后的查阅和复习。

首先举个例子

foo();//undefined
function foo(){
console.log(a);//undefined
var a = 10;
}

上面的例子中,foo()函数的声明在调用之后,但是还是会输出函数中的结果。在foo()函数的内部,变量a的声明之前就调用了,但是系统会输出undefined,而不会报错,这里面就涉及到了变量提升还有函数提升,为什么会出现这样的情况呢,先来了解几个重要的概念,就可以解开这个谜底了。

一、什么是执行上下文

每次当控制器转到可执行代码的时候,就会进入一个可执行上下文。执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。

一个执行上下文的生命周期



从图中可以看出,一个执行上下文的生命周期包括创建执行两个阶段。

1、第一个阶段中做的工作有:

  • 生成变量对象
  • 建立作用域链
  • 确定this的指向

2、第二个阶段中做的工作有:

  • 变量赋值
  • 函数引用
  • 执行其他代码

到这里还不能解析为什么会有变量提升和函数提升的过程,那么我们接下来再深入执行上下文中的创建阶段中的生成变量对象的过程

什么是变量对象

在很多面试题中,会考到变量对象和活动对象的区别,其实活动对象和变量对象是同一个对象,只是处于执行上下文的不同生命周期而已,活动对象处于执行阶段。

从图中可以看出,在生成变量对象的过程中,执行的操作有三步

1、创建arguments对象

2、检查functfen函数声明创建属性

3、检查var变量声明创建属性

所以在了解完执行上下文和变量对象后,就可以分析一下我们的问题了。
当我们执行第一句话的时候foo(),javascript引擎会创建一个执行上下文testEc,并且生成一个变量对象VO,首先创建argument对象,然后检查function函数声明并且创建一个属性,所以就生成了如下的vo对象
创建过程
testEC = {
// 变量对象
VO: {},
scopeChain: {},
this: {}
} // 因为本文暂时不详细解释作用域链和this,所以把变量对象专门提出来说明 // VO 为 Variable Object的缩写,即变量对象
VO = {
arguments: {...}, //注:在浏览器的展示中,函数的参数可能并不是放在arguments对象中,这里为了方便理解,我做了这样的处理
foo: <foo reference> // 表示foo的地址引用
a: undefined
}
变量提升也是同样的道理。

谈谈javascript中的变量提升还有函数提升的更多相关文章

  1. <javaScript>谈谈JavaScript中的变量、指针和引用

    1.变量我们可能产生这样一个疑问:编程语言中的变量到底是什么意思呢?事实上,当我们定义了一个变量a时,就是在存储器中指定了一组存储单元,并将这组存储单元命名为a.变量a的值实际上描述的是这组存储单元中 ...

  2. 谈谈JavaScript中的变量、指针和引用

    1.变量 我们可能产生这样一个疑问:编程语言中的变量到底是什么意思呢? 事实上,当我们定义了一个变量a时,就是在存储器中指定了一组存储单元,并将这组存储单元命名为a.变量a的值实际上描述的是这组存储单 ...

  3. 在javascript中关于变量与函数的提升

    在javascript中关于变量与函数的提升 一.简介 在javascript中声明变量与函数的执行步骤: 1.先预解析变量或函数声明代码,会把用var声明的变量或者函数声明的代码块进行提升操作 2. ...

  4. JavaScript系列文章:变量提升和函数提升

    第一篇文章中提到了变量的提升,所以今天就来介绍一下变量提升和函数提升.这个知识点可谓是老生常谈了,不过其中有些细节方面博主很想借此机会,好好总结一下. 今天主要介绍以下几点: 1. 变量提升 2. 函 ...

  5. JavaScript:变量提升和函数提升

    第一篇文章中提到了变量的提升,所以今天就来介绍一下变量提升和函数提升.这个知识点可谓是老生常谈了,不过其中有些细节方面博主很想借此机会,好好总结一下. 今天主要介绍以下几点: 1. 变量提升 2. 函 ...

  6. 对javascript变量提升跟函数提升的理解

    在写javascript代码的时候,经常会碰到一些奇怪的问题,例如: console.log(typeof hello); var hello = 123;//变量 function hello(){ ...

  7. JavaScript: 变量提升和函数提升

    第一篇文章中提到了变量的提升,所以今天就来介绍一下变量提升和函数提升.这个知识点可谓是老生常谈了,不过其中有些细节方面博主很想借此机会,好好总结一下. 今天主要介绍以下几点: 1. 变量提升 2. 函 ...

  8. js中变量提升和函数提升

    变量提升和函数提升的总结 我们在学习JavaScript时,会遇到变量提升和函数提升的问题,为了理清这个问题,现做总结如下,希望对初学者能有所帮助 我们都知道 var 声明的变量有变量提升,而 let ...

  9. 关于Javascript中声明变量、函数的笔记

    一.概念 1.变量声明 在JavaScript中,变量一般通过var关键字(隐式声明,let关键字声明除外)进行声明,如下通过var关键字声明a,b,c三个变量(并给其中的a赋值): var a=1, ...

随机推荐

  1. TensorFlow的前世和今生

    TensorFlow的前世和今生 TensorFlow是一个开放源码的软件库,用于跨一系列任务的数据流处理编程.TensorFlow是一个符号化的数学应用库,广泛用于机器学习,例如神经网络.在谷歌公司 ...

  2. 关于osi的7层与tcp的4层网络协议的理解

    osi 七层模型 应用层 提供接口 表示层 机器语言的二进制转换 对话层 决定是否传输 传输层 确定可不可靠 排差错 控流 网络层 提供逻辑地址 选路 数据链路层 mac 错误检测 物理层 设备间的比 ...

  3. 请给出如下格式的date命令 例:11-02-26.再给出实现按周输出 比如:周六输出为6,请分别给出命令。

    请给出如下格式的date命令 例:19-01-18.再给出实现按周输出 比如:周六输出为6,请分别给出命令. 解答: 方法1: [root@zhaokang ~]# date2019年 01月 17日 ...

  4. Linux下Tomcat性能优化--文件句柄数增大

    今天在对项目进行性能压力测试时,设置并发量为1000,发现Tomcat控制报错: java.IOException:打开的文件过多 经搜索,发现是由于Linux默认设置的句柄数为1024,当并发量过大 ...

  5. 学习html的第一天

    HTML 第一章: webde 运行环境: 1. 什么是HTML HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言:HyperText Markup Languge 超文本 就是网 ...

  6. .NET Core On Liunx环境搭建之MongoDB

    伴随着.NET Core的开源,Liunx服务器才是.NET 的未来,公司前几天刚刚上新了一台Liunx服务器,我进行了一下环境的搭建,把经验分享出来. 服务器信息:  服务器用的是阿里云服务器,操作 ...

  7. mysql主键重复,不抱错,只更新的骚操作 (如果没有插入,如果有更新)

    平时我们在设计数据库表的时候总会设计 unique  或者 给表加上 primary key 的限制条件. 此时 插入数据的时候 ,经常会有这样的情况: 我们想向数据库插入一条记录: 若数据表中存在以 ...

  8. IComparer 与 IComparable

    static void Main() { var people = new ArrayList(); people.AddRange(new ArrayList { }, }, }, } }); Co ...

  9. centos6.9安装虚拟机kvm

    说明 以下所有操作都基于centos6.9 查看系统是否支持虚拟化 结果有vmx|svm才支持虚拟化 egrep '(vmx|svm)' --color=always /proc/cpuinfo 系统 ...

  10. Ruby中Enumerable模块的一些实用方法

    我在查看 Array 类和 Hash 类的祖先链的时候都发现了 Enumerable,说明这两个类都mixin了Enumerable模块.Enumerable模块为集合型类提供了遍历.检索.排序等方法 ...