大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新......

在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目。现在就让我们一起进入 Web 前端学习的冒险之旅吧!

js变量提升与函数提升的详细过程

先来看两个栗子,下面的两段代码分别输出什么?

// 代码段1
function foo() {
var a = 1;
function a() {}
console.log(a);
}
foo(); // 代码段2
function foo() {
var a;
function a() {}
console.log(a);
}
foo();

答案是:代码段1打印的是1,代码段2打印的是 a() 函数。

为什么会这样呢?这就涉及到js中的变量提升和函数提升的具体过程了。

1、变量的提升

js是怎么创建变量的呢?

如下面的代码:

var a = 1;
var b = 2;

js在解析上面的代码的时候,其实会按照下面的方式进行解析的:

var a;
var b;
a = 1;
b = 2;

所以 js 并不是在我们定义一个变量的时候,声明完成之后立即赋值,而是把所有用到的变量全部声明之后,再到变量的定义的地方进行赋值,变量的声明的过程就是变量的提升。

所以我们看下下面的栗子:

function foo() {
var a = 1;
console.log(a);
console.log(b);
var b = 2;
}
foo();

上面的代码在js的眼中是这样解析的:

function foo() {
var a;
var b;
a = 1;
console.log(a); // 1
console.log(b); // undefined
b = 2;
}
foo();

所以输出的 a 的值为1, b的值为 undefined。

变量在声明提升的时候,是全部提升到作用域的最前面,一个接着一个的。但是在变量赋值的时候就不是一个接着一个赋值了,而是赋值的位置在变量原本定义的位置。原本js定义变量的地方,在js运行到这里的时候,才会进行赋值操作,而没有运行到的变量,不会进行赋值操作。

所以变量的提升,提升的其实是变量的声明,而不是变量的赋值。

2、函数的提升

函数的提升和变量的提升类似,都是提升到作用域的最开始的位置,只不过变量的提升是分两步的,第一步是变量声明的提升,第二步是变量的赋值。而函数的提升是直接将整个函数整体提升到作用域的最开始位置,相当于剪切过去的样子。

3、变量提升和函数提升的顺序

在作用域中,不管是变量还是函数,都会提升到作用域最开始的位置,不同的是,函数的提升后的位置是在变量提升后的位置之后的。

举个栗子:

下面的代码输出什么?

function foo() {
console.log(a);
var a = 1;
console.log(a);
function a() {}
console.log(a);
}
foo();

上面的代码在js眼中是这样解析的:

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

所以从上面的栗子可以看到,变量的提升是在函数提升之前的,但是变量赋值的部分是在js原型到变量定义的位置才给变量赋值的,而函数提升是相当于直接剪切到最前面的。

我们再看一个更加复杂一点的栗子:

function foo() {
console.log(a);
var a = 1;
console.log(a);
function a() {}
console.log(a);
console.log(b);
var b = 2;
console.log(b);
function b() {}
console.log(b);
} foo();

js是这样解析的:

function foo() {
var a;
var b;
function a() {}
function b() {}
console.log(a); // a()
a = 1;
console.log(a); // 1
console.log(a); // 1
console.log(b); // b()
b = 2;
console.log(b); // 2
console.log(b);// 2
}
foo();

最后,注意:只有声明的变量和函数才会进行提升,隐式全局变量不会提升。

下面的栗子中,b不会进行变量提升。

function foo() {
console.log(a);
console.log(b); // 报错
b = 'aaa';
var a = 'bbb';
console.log(a);
console.log(b);
}
foo();

4、参考链接

js变量提升与函数提升的机制: https://segmentfault.com/a/1190000008568071

js变量提升与函数提升的详细过程的更多相关文章

  1. js中的变量提升和函数提升

    从上周开始,我所在的学习小组正式开始了angular的学习,angular是全面支持es6的,所以语法上和以前的angular有了很大的不同,比如变量声明时就抛弃了var,而选择了let和const: ...

  2. 浅谈JS变量声明和函数声明提升

    先来两个问题 很多时候,在直觉上,我们都会认为JS代码在执行时都是自上而下一行一行执行的,但是实际上,有一种情况会导致这个假设是错误的. a = 2; var a; console.log(a); 按 ...

  3. JS 变量提升与函数提升

    JS 变量提升与函数提升 JS变量提升 变量提升是指:使用var声明变量时,JS会将变量提升到所处作用域的顶部.举个简单的例子: 示例1 console.log(foo); // undefined ...

  4. JS逻辑题 技术点: 1). 变量提升 2). 函数提升 3). 预处理 4). 调用顺序

    考查的技术点:  1). 变量提升 2). 函数提升  3). 预处理  4). 调用顺序 var c = 1; function c(c) { console.log(c); var c = 3; ...

  5. JS——变量提升和函数提升

    一.引入 在了解这个知识点之前,我们先来看看下面的代码,控制台都会输出什么 var foo = 1; function bar() { if (!foo) { var foo = 10; } aler ...

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

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

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

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

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

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

  9. 谈谈javascript中的变量提升还有函数提升

    在很多面试题中,经常会看到关于变量提升,还有函数提升的题目,所以我就写一篇自己理解之后的随笔,方便之后的查阅和复习. 首先举个例子 foo();//undefined function foo(){ ...

随机推荐

  1. (摘录)Java 详解 JVM 工作原理和流程

    作为一名Java使用者,掌握JVM的体系结构也是必须的. 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言.Java类文件格式.Java ...

  2. fiddler不能抓某些的包的原因

    用fiddler抓某app的包时,死活抓不到,确定自己设置的没有错,并且让小A同事也看了一遍我的设置,确认没错后,又在小A同事那儿试了下还是抓不到 后来在网上找了很多资料,才发现是因为一些app使用了 ...

  3. C# MVC验证Model

    .NET Core MVC3 数据模型验证的使用 这里我先粘贴一个已经加了数据验证的实体类PeopleModel,然后一一介绍. using System; using System.Collecti ...

  4. metasploit生成payload的格式

    转自https://www.cnblogs.com/zlgxzswjy/p/6881904.html Often one of the most useful (and to the beginner ...

  5. 【慕课网实战】五、以慕课网日志分析为例 进入大数据 Spark SQL 的世界

    提交Spark Application到环境中运行spark-submit \--name SQLContextApp \--class com.imooc.spark.SQLContextApp \ ...

  6. vue监听滚动事件-元素固定位置显示

    1.监听滚动事件 用VUE写一个在控制台打印当前的scrollTop用来测试是否执行: mounted () { window.addEventListener('scroll', this.hand ...

  7. <<君主论>>读后感

    “<君主论>与<圣经>齐名,被称为邪恶的圣经,这本书的立论基础是人性本恶论,他所描述的人性之恶,主要是以西欧资本原始积累背景下的现实社会中人的各种丑恶现象为蓝本的.” 要是高中 ...

  8. 211806385 黄存慧 https://www.cnblogs.com/huangch/ https://github.com/HuangCh327

    211806385 黄存慧 https://www.cnblogs.com/huangch/ https://github.com/HuangCh327

  9. display:inline-block; 在css中是什么意思?

    inline-block主要的用处是用来处理行内非替换元素的高宽问题的!行内非替换元素,比如span.a等标签,正常情况下士不能设置宽高的,加上该属性之后,就可以触发让这类标签表现得如块级元素一样,可 ...

  10. Python小练习之判断一个日期是一年的第几天

    python练手遇到的一个问题写了个统一公式,不用麻烦的分各种类,如果有人测试出错误请评论通知. #分单双月 def dayNum(month,day,isLeap): if month % 2 != ...