前言
在官方文档处学习了JS作用域后,总觉得理解的不够全面,博客翻了一大堆但仍然存在一些漏洞,希望尽可能多验证完善。
作用域的问题离不开变量提升,可参考另一篇文章记录了我学习→变量提升的过程。
ES6之前只有全局作用域和函数作用域的概念,ES6新增块级作用域,推荐使用let & const局部变量。
本文以区分var 和 let为目的出发,讲解两种声明关键字在作用域下的区别。
当然,本文提到的概念还是比较浅的,更深层次的概念还是推荐去官方文档进行完整的学习。
一、使用var关键字声明
看示例1:
var a = 'a'
console.log(1, a)
function func1() {
console.log(2, a)
}
结果:

在func1函数作用域内没找到变量a,会继续朝上一级作用域查找,直到全局作用域。
再看示例2:
var a = 'a'
console.log(1, a)
function func1() {
console.log(2, a)
var a = 'aa'
console.log(3, a)
}
func1()
console.log(4, a)
if (true) {
console.log(5, a)
var a = 'aaa'
console.log(6, a)
}
console.log(7, a)
结果:

分析:
a. 变量a在func1函数作用域进行了声明,此a非外层作用域的a,所以第2条打印结果与示例1不一样,由于变量提升,仅声明未赋值结果为undefined,无论在func1内如何修改变量a都不会影响外层作用域的变量a;
b. 变量a在if的{}块级作用域(针对let变量才起作用,这里是做对比)内进行了var声明和定义为 ‘aaa’,但由于var的变量提升,声明提升到了当前所处函数作用域顶部(这里是全局作用域),于是在if内给a赋值其实是对全局变量a的赋值;
c. 未声明的变量,会自动提升到全局,成为一个全局变量(这样不好):

会打印出该变量:

不调用该方法执行这行代码,也就不会存在该变量:

二、使用let 关键字声明
示例1:
let a = 'a'
console.log(1, a)
function func1() {
console.log(2, a)
}
结果:

与var声明效果是一致的,当前func1函数作用域(此时得称为块级作用域)没a,向上一级作用域查找,直到全局作用域。
再看示例2
let b = 'b'
console.log(1, b)
function func1() {
// console.log(2, b) // 此处打印会报错 后续会列出let的两种错误
let b = 'bb'
console.log(3, b)
}
func1()
console.log(4, b)
if (true) {
console.log(5, b)
b = 'bbb'
console.log(6, b)
}
console.log(7, b)
结果:

分析:
a. 在func1的块级作用域里,声明了let b并赋值,此b非外层作用域的b,仅在当前作用域有效;
b. 在if{}块级作用域内,对变量b进行赋值,此时变量b就是外层作用域的b,所以全局作用域下的b也被修改了,当然也可以在if{}内声明变量b,此时变量b就与func1里的b一样是单独的作用域下的变量:

结果是:

c. let声明的变量不存在变量提升,所以 let变量的使用,需要在声明之后,这是两种作用域下的未声明就使用的错误:


三、后续追加
1.在全局作用域下声明的let变量不能通过this获取到:

可以看到变量a并不在Globa对象下,而是Script…
持续更新~
最后
以上就是威武冰棍最近收集整理的关于JavaScript-作用域下var/let的区别-学习验证前言一、使用var关键字声明二、使用let 关键字声明三、后续追加的全部内容,更多相关JavaScript-作用域下var/let的区别-学习验证前言一、使用var关键字声明二、使用let内容请搜索靠谱客的其他文章。
发表评论 取消回复