大家好,这里是「 从零开始学 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. 关于管理,你可能一直有 3 个误解zz

    很多管理者认为,下属绩效低是由于其能力不行.其实,下属的绩效是由管理者决定的.一个好的管理者,必须对管理有正确的认知,才能形成有效的管理行为,让下属拥有绩效,并获得成长.来源丨春暖花开(ID:CCH_ ...

  2. php hash_file

    string hash_file ( string $algo , string $filename [, bool $raw_output = FALSE ] ) 参数¶ algo 要使用的哈希算法 ...

  3. java操作FTP的一些工具方法

    java操作FTP还是很方便的,有多种开源支持,这里在apache开源的基础上自己进行了一些设计,使用起来更顺手和快捷. 思路: 1.设计FTPHandler接口,可以对ftp,sftp进行统一操作, ...

  4. PowerShell工作流学习-6-向脚本工作流添加检查点

    关键点: a)检查点是工作流当前状态的快照,其中包括变量的当前值以及在该点生成的任何输出,这些信息保存在磁盘. b)检查点数据保存在托管工作流会话的计算机的硬盘上的用户配置文件中. c)当工作流通用参 ...

  5. windows安装zookeeper

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提供的功 ...

  6. 利用python list 完成最简单的DB连接池

    先来看查看效果: 在代码连接数据库后,并且执行三条sql后,将mysql直接重启掉,故我们的连接池连接均是不ok的,所以,它会全部删除再抓新的连接下来,重启mysql命令: 关于python代码: # ...

  7. python for data analysis 2nd 读书笔记(一)

    第一章相对简单,也么有什么需要记录的内容,主要用到的工具的简介及环境配置,粗略的过一下就行了.下面我们开始第二章的学习 CHAPTER 22.2Python Language Basics, IPyt ...

  8. BZOJ4720-换教室

    题目很长,是一道概率dp题,一般需要逆推,但这题结局不确定所以要顺推. 用f[i][j][k],i表示第i段时间,j表示用了j次申请,k就表示这轮是否用申请. 那么要求min(f[n][0~m][0] ...

  9. 2.Spring 拦截器应用

    首先咱们来了解一下具体的业务场景(这个跟第一篇中的很相似但有不同):具体的业务是这样的,现在系统中有六十多个主档(功能模块),每个主档都有新增.修改.删除功能,当我们在对每个主档做这些操作时需要对其记 ...

  10. MySQL基础知识3