每日一题(开开森森学前端之变量与函数)
前言
大家好,今天我们来看一下js中的变量与函数提升相关知识点
为什么有变量提升
js和其他语言一样,都要经历编译和执行阶段。而js在编译阶段的时候,会搜集所有的变量声明并且提前声明变量,而不会改变其他语句的顺序,因此,在编译阶段的时候,第一步就已经执行了,而第二步则是在执行阶段执行到该语句的时候才执行。
相关题目与解析
先从一个简单的例子来入门:
a = 2;
var a;
console.log(a);
复制代码
你觉得以上的代码会输出什么?是输出undefined
吗?如果是按照程序的自上而下执行的话,那么这一段代码确实是输出undefined,因为var a
语句把a = 2
的语句给覆盖了。然而,javascript
并不是严格的自上而下执行的语言。
这一段代码的输出结果是2
,是不是感到很意外?为什么会这样呢?这个问题的关键就在于变量提升(hoisting
)。它会将当前作用域的所有变量的声明提升到程序的顶部,因此上面的代码其实等价于以下代码。这样是不是就很简单明了了。
var a;
a = 2;
console.log(a);
复制代码
那么接下来,我们再来看这个例子。
console.log(a);
var a = 2;
复制代码
你觉得以上的代码会输出什么?是直接报ReferenceError
吗?还是输出2
呢?
其实以上代码会输出undefined
。为什么呢?我们之前说过,js会将变量的声明提升到顶部,可是赋值语句并不会提升。所以对于js来说,其实var a = 2
是分为两步的:
1.var a;
2.a = 2;
复制代码
而js只会将第一步提升到顶部,所以上面的语句等价于:
var a;
console.log(a);
a = 2;
复制代码
js的变量声明其实大体上可以分为三种:var
声明、let
与const
声明和函数声明
。
函数声明与其他声明一起出现的时候,就可能会引起一些困扰。我们来看下面的例子。
foo();
function foo() {console.log('foo');
}
var foo = 2;
复制代码
你觉得上面会输出什么?TypeError
吗?还是输出foo
呢?想一想再接着往下看。
当当当当,其实最后输出的结果是foo
。这就引出了我们的问题了,当函数声明与其他声明一起出现的时候,是以谁为准呢?答案就是,函数声明高于一切!
那么,下面的例子呢?
foo();
function foo() {console.log('1');
}
function foo() {console.log('2');
}
复制代码
当出现多个函数声明,那怎么办呢?
上面这个代码输出结果为2
。因为有多个函数声明的时候,是由最后面的函数声明来替代前面的。
想必经历了以上的例子,你应该已经对变量声明已经有一定的了解了。那么我再来出一道题目来测试下。
foo();
var foo = function() {console.log('foo');
}
复制代码
这道题目是不是非常简单啊?这道题和上面的第二道例子其实是一样的。var foo = function() {}
这种格式我们叫做函数表达式
。
它其实也是分为两部分,一部分是var foo
,而一部分是foo = function() {}
,参照例2
,我们可以知道,这道题的结果应该是报了TypeError
(因为foo
声明但未赋值,因此foo
是undefined
)。
上面我们提到了var声明,函数声明,那么接下来我们来讲讲let
和const
声明。
let
和const
其实也是有函数提升的概念,不过它们会比较特殊,与var
不一样,它们存在一个临时(暂时)性死区的概念。我们可以通过一个例子来体现这一点。
var a = 2;
function test() {console.log(a);let a = 5;
}
test();
复制代码
你觉得上面的代码会输出什么呢?是输出2
javascript,还是undefined
呢?
如果说,let没有变量提升的效果的话,那么应该是输出2
。如果说let
拥有和var
一样的变量提升效果的话,那么应该是输出undefined
。然而,其实上面的代码是会报错的。会报"ReferenceError: a is not defined
"错误。那么为什么呢?
这其实就是我说的,let
虽然具有变量提升的功能,但是它又与var
不一样,它具有一个临死性死区的概念。
临死性死区其实就是说,a
我已经声明了,可是在没有到它赋值的时候,你都不能使用这个变量,不然就会报错。所以该当前作用域开始,一直到let a = 5
为止这整一块,都是a
变量的临死性死区,你不能使用它。
而const
和let
它们的变量提升的效果是一样的,也都存在着临死性死区的概念。
总结
js会将变量的声明提升到js顶部执行。
因此对于这种语句:var a = 2
;
其实上js会将其分为var a;
和a = 2;
两部分,并且将var a
这一步提升到顶部执行。
变量提升的本质其实是由于js引擎在编译的时候,就将所有的变量声明了,因此在执行的时候,所有的变量都已经完成声明。
当有多个同名变量声明的时候,函数声明会覆盖其他的声明。如果有多个函数声明,则是由最后的一个函数声明覆盖之前所有的声明。
let
和const
都具有变量提升的效果,但是它们都具有临死性死区,从作用域开始部分,一直到变量的声明语句这整一块,你都不能使用该变量。
大佬们如果发现了文中的错误,请在评论区指出,我会及时修正!
如果觉得对您有用请点个赞,谢谢大佬!
每日一题(开开森森学前端之变量与函数)相关推荐
- 面试准备每日五题:C++(一)——变量定义声明、#ifdef #else、结构体赋值、sizeof strlen、C和C++的static
文章目录 1 变量的声明和定义有什么区别? 2 简述#ifdef.#else.#endif和#ifndef的作用 3 结构体可以直接赋值吗? 4 sizeof 和strlen 的区别 5 C 语言的关 ...
- 对数函数定义域和值域_呆哥数学每日一题 —— 复合函数值域
如果想要获取往期每日一题电子版,可以加我微信:daigemath366,备注:知乎 每日一题 呆哥解析:这是一个函数和复合函数的综合问题 首先我们先把原函数的值域求出来 先直接求导: 导数不容易判断单 ...
- 学前端的后果原来这么严重?! | 每日趣闻
戳一戳小程序查看更多! 往 期 趣 闻 ☞好听!前端竟然自己会变调!| 每日趣闻 ☞修完 Bug 后脑袋灵光一现 | 每日趣闻 ☞如果孩子想学编程,你会推荐哪个?| 每日趣闻 ☞那些令人羡慕的工位布置 ...
- dom更新到底在javascript事件循环的哪个阶段?「前端每日一题v22.11.17」
dom更新到底在javascript事件循环的哪个阶段?「前端每日一题v22.11.17」 昨天写了一篇文章,是javascript的事件循环机制,然后在某乎上也发了,在发的时候看到了一个问题,dom ...
- 倪文迪陪你学蓝桥杯2021寒假每日一题:2.1日(2019省赛A组第10题)
2021年寒假每日一题,2017~2019年的省赛真题.本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供.每日一题,关注蓝桥杯专栏: https://blog.csdn.net/w ...
- 新玩法来了,web前端教程公众号推出《每日一题》
<每日一题>是一种新玩法,怎么玩?很简单. 直接回复 "我要做题" ,将获取最新一期的习题. 比如: 写下你认为正确的答案,回复给公众号. 还可以回复历史期号,查看历史 ...
- 倪文迪陪你学蓝桥杯2021寒假每日一题:1.11日(2017省赛A第9题)
2021年寒假每日一题,2017~2019年的省赛真题. 本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供. 后面的每日一题,每题发一个新博文,请大家看博客目录:https://b ...
- 倪文迪陪你学蓝桥杯2021寒假每日一题:1.20日(2018省赛A组第8题)
2021年寒假每日一题,2017~2019年的省赛真题. 本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供. 后面的每日一题,每题发一个新博文,请大家每天看博客蓝桥杯专栏: htt ...
- 倪文迪陪你学蓝桥杯2021寒假每日一题:1.19日(2018省赛A组第7题)
2021年寒假每日一题,2017~2019年的省赛真题. 本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供. 后面的每日一题,每题发一个新博文,请大家每天看博客蓝桥杯专栏: htt ...
最新文章
- Android EditText不弹出输入法焦点问题的总结
- 腾讯视频怎么设置下载视频位置
- 【OpenCV 例程200篇】41. 图像的灰度变换(灰度级分层)
- IP地址子网的划分机制
- 利用R与NumPy实现矩阵乘法
- 「CodePlus 2017 11 月赛」Yazid 的新生舞会(树状数组/线段树)
- JavaScript快速基础入门
- 围棋人机大战一周年:被AlphaGo改变的世界
- Java设计模式之观察者模式应用与实战
- linux上挂载iso文件,如何在Linux上挂载ISO文件
- Oracle配置本地网络服务名
- mac蓝牙连接有问题要怎么处理呢?
- IO缓冲(buffer)和高速缓存(cache)
- chrome浏览器自动填充时背景色改变(-webkit-autofill)
- 数据结构-图、二叉树、B(+)树
- 手机app和单片机蓝牙通讯c语言,单片机怎么和手机通信,你知道吗?
- Typo: In word 拼写检查
- 数字经济之新零售行动派:鸡毛换糖走向数智化
- VS Code 遇上 Java丨第二章:配置 Maven 构建工具
- 为什么加了@WebFilter注解,Spring却没有给我自动注入该过滤器?