变量提升真的搞懂了吗?打脸的一道题

我们知道JS代码在执行之前,会做一系列的事情,其中就包括变量提升,原本以为把变量提升搞懂的我(因为这两天一直在研究变量提升,自我感觉已经很良好了,哈哈哈),拿到了一道打脸的题。当然了,拿给身边的程序员朋友们,做对的也......废话不多说,一起来看下这道题吧。

1. 题目

var a = 0;
if (true) {a = 1;function a() {};a = 21;console.log(a)
}
console.log(a);

答案:21 1

2. 重新学习变量提升

2.1 var

首先说使用var声明的变量,只要那个变量是使用var声明的,那么在变量提升阶段要做的事情只有一个,就是去声明这个变量。

一道简单的题目看懂var的变量提升

console.log(a);
var a = 1;
console.log(a);

  • 在代码执行之前先创建一个变量a;此时并不会进行赋值等操作
  • 代码执行
    • console.log(a);因为此时已经有a这个变量了,只不过没有赋值,因此输出undefined
    • var a = 1;给变量a进行赋值为1
    • console.log(a);这时候再输出a的值,就是上面的赋值结果1

控制台查看输出结果

2.2 let const

我们知道使用let和const声明的变量没有变量提升,只有当代码走到那一行才会去执行声明等操作;

2.3 function

function fn(){...}没有在if/for等任何大括号内的时候,它会声明+定义,即:

  • 把右边的值存储在堆内存中,并把堆内存地址存储在栈内存;
  • 然后声明变量fn,
  • 最后让fn和堆地址关联

但如果把上面的这句话放在if/for这样的大括号内的时候,就变成下面这样的过程了:

  • 声明一个变量fn存储在栈内存中
  • 当满足条件进入到大括号内的时候
    • 第一件事情就是定义这个函数:即让这个变量名和堆地址进行关联。注意此时这个变量fn已经变为这个块内私有的变量了,和外面的fn没有任何关系;
    • 当代码执行过程中,遇到function fn(){...}的时候,它会去把全局中的fn修改一下,修改为堆中fn的值。修改完之后,后面对fn的操作又和全局的fn没任何关系

3.看穿题目的'庐山真面目'

这道题就是利用上面的所说到function的变量提升情况。即当在if/for中存在函数,并且条件成立,那么这个函数就变为私有,直到遇到function fn(){...}的时候才会去操作全局的fn,其它情况操作的fn都是私有的。

下面是这道题的图解过程

4. 同类型题目的练习

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

5. 总结

这也是浏览器为了解决新老版本改善的function的变量提升机制,可以看出也是在一步步的完善,因此我们也要不断的学习,才可以跟上互联网的快速发展。

inputstream重新赋值之前需要close吗_变量提升真的搞懂了吗?打脸的一道题相关推荐

  1. layer output 激活函数_一文彻底搞懂BP算法:原理推导+数据演示+项目实战(下篇)...

    在"一文彻底搞懂BP算法:原理推导+数据演示+项目实战(上篇)"中我们详细介绍了BP算法的原理和推导过程,并且用实际的数据进行了计算演练.在下篇中,我们将自己实现BP算法(不使用第 ...

  2. cas无法使用_一文彻底搞懂CAS实现原理

    本文导读: 前言 如何保障线程安全 CAS原理剖析 CPU如何保证原子操作 解密CAS底层指令 小结 前言 日常编码过程中,基本不会直接用到 CAS 操作,都是通过一些JDK 封装好的并发工具类来使用 ...

  3. cookie代码加时间多久出现一次_一文彻底搞懂Cookie、Session、Token到底是什么

    前言 在了解这三个概念之前我们先要了解HTTP是无状态的Web服务器,什么是无状态呢?就像上面夏洛特烦恼中经典的一幕对话一样,一次对话完成后下一次对话完全不知道上一次对话发生了什么.如果在Web服务器 ...

  4. 访问网址 token的格式_一文彻底搞懂Cookie、Session、Token到底是什么

    欢迎关注文章系列 ,关注我 <提升能力,涨薪可待> <面试知识,工作可待> <实战演练,拒绝996> 如果此文对你有帮助.喜欢的话,那就点个赞呗,点个关注呗! Co ...

  5. java transient关键字_小伙子,你真的搞懂 transient 关键字了吗?

    先解释下什么是序列化 我们的对象并不只是存在内存中,还需要传输网络,或者保存起来下次再加载出来用,所以需要Java序列化技术. Java序列化技术正是将对象转变成一串由二进制字节组成的数组,可以通过将 ...

  6. mysql三次握手_一文彻底搞懂 TCP三次握手、四次挥手过程及原理

    原创文章首发于公众号:「码农富哥」,欢迎收藏和关注,如转载请注明出处! TCP 协议简述 TCP 提供面向有连接的通信传输,面向有连接是指在传送数据之前必须先建立连接,数据传送完成后要释放连接. 无论 ...

  7. redis 集群搭建_一文轻松搞懂redis集群原理及搭建与使用

    转载:https://juejin.im/post/5ad54d76f265da23970759d3 作者:SnailClimb 这里总结一下redis集群的搭建以便日后所需同时也希望能对你有所帮助. ...

  8. java开发可重用代码包工具包_[Java教程]彻底搞懂Java开发工具包(JDK)安装及环境变量配置...

    [Java教程]彻底搞懂Java开发工具包(JDK)安装及环境变量配置 0 2021-01-04 04:00:04 安装并配置JDK环境变量,不但要知道怎样做,也要知道为什么这样做,知其然知其所以然. ...

  9. 最大信息熵增益_机器学习笔记(三)——搞懂决策树必备的信息增益

    一.何为决策树 决策树是监督学习算法之一,并且是一种基本的分类与回归方法:决策树也分为回归树和分类树,本文讨论的是分类树.如果了解或者学过数据结构,肯定对"树"这个概念是不陌生的, ...

最新文章

  1. DEV为什么不能输出小数 浮点数?
  2. 无需u盘和光盘安装linux
  3. “一线城市,年薪30万+,我却裸辞回老家”一个前程序员的 10 年职业思考
  4. PyTorch 《动手学深度学习》学习笔记(Dive-into-DL-Pytorch)
  5. SQL Server 审计
  6. C++面试宝典 基本语言(三)
  7. 字符串匹配算法(KMP)
  8. android系统框架()
  9. eds800变频器故障代码_干货|三菱变频器故障剖析,及严重故障和轻微故障判断技巧!...
  10. Linux常见命令(一)
  11. 设计模式原则之六:依赖倒置原则
  12. ionic3编译到Android 相关配置
  13. 模糊控制 进化算法 PID参数整定
  14. 城市数据大脑:小汽车儿堵成翔?NONONO!
  15. asp内乱码,注意不是ajax
  16. Ubuntu下载常用软件和使用Caffe时的常见问题
  17. NanoPi R2S 专用软件源
  18. 聚观早报 | 百度糯米发布下线公告;零跑汽车获港交所上市批准
  19. Zabbx6.0(学习笔记)
  20. js的setCapture

热门文章

  1. linux程序莫名异常怎么查
  2. 数据处理不等式:Data Processing Inequality
  3. 使用栈实现队列 Implement Queue using Stacks
  4. Xtrabackup数据全备份与快速搭建从服务器
  5. MyBatis_ibatis和mybatis的区别【转】
  6. Javascript验证上传图片大小[前台处理]
  7. 判断整数序列是不是二元查找树的后序遍历结果
  8. GitHub动作简介
  9. leetcode 435. 无重叠区间
  10. leetcode784. 字母大小写全排列(回溯)