js|JavaScript全局作用域、函数作用域和块级作用域的区别

作用域(Scope):函数和变量的使用范围
全局作用域:函数外部的作用域
函数作用域;函数内部的作用域
块级作用域:{ } 包裹着的代码
一、全局作用域

let uname = "奥特曼" function getName() { console.log(uname); //奥特曼 } getName() console.log(uname); //奥特曼

不管是函数里面还是函数外面都可以访问到uname变量
总结:在函数外面定义的变量,在页面的任何地方都可以访问
二、函数作用域 在es5中只有 全局作用域和函数作用域
function getName() { let uname = "奥特曼" var age = "20" console.log(age); console.log(uname); //奥特曼 } getName() console.log(age); // age is not defined console.log(uname); //uname is not defined

注意点 全局输出时age和uanem是单独输出的,因为在执行过程中,如果前面的代码报错,就会阻塞后面的代码继续执行
当前的uname和age是在函数内部定义的,uname和age就是局部变量,只有函数内部可以访问(不包括函数嵌套,父访问子)
为什么在全局访问不到函数内部定义的变量呢? 在调用getName的时候,函数会新开辟一个作用域空间,等函数执行完以后,函数会把这个作用域关闭,并且把变量也进行销毁
三、块级作用域(block)在es6中新增了块级作用域:被 { } 包裹住的代码就是块级作用域( 包括函数中的{ }、if、for)
if(true){ let uname = '奥特曼' var age="20" console.log(age); //20 console.log(uname); // //奥特曼 } console.log(age); //20 console.log(uname); //uname is not defined

同样发现 在{ }中定义的变量,用let声明的变量 在{ } 外部同样访问不到 ,但是用var 声明的可以访问到,我们到断点去看一下
js|JavaScript全局作用域、函数作用域和块级作用域的区别
文章图片

我们发现用let 定义的变量 放到了Block区块中,而var声明的变量放在了Global全局当中,所以说var在块级作用域下我们可以进行访问
查了资料看到MDN说
js|JavaScript全局作用域、函数作用域和块级作用域的区别
文章图片

个人理解就是var定义的变量 不管在哪定义的,都会放到window下 所以用的都是同一个作用域。

接下来看let中在{ }定义的变量
js|JavaScript全局作用域、函数作用域和块级作用域的区别
文章图片

【js|JavaScript全局作用域、函数作用域和块级作用域的区别】let 和 const定义的变量是有块级作用域的,只能在当前块作用域访问
总结访问变量的区别
var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。

总结完之后再来看看为什么es6会增加块级作用域呢,知道概念不行,更要知道原理哦
1. 内层变量覆盖外层变量
//es5 var uname = "奥特曼" function fn() { console.log(uname); //undefined if(false){ var uname = "怪兽" } } fn()//es6 var uname = "奥特曼" function fn() { console.log(uname); //奥特曼 if(false){ let uname = "怪兽" } } fn()

由于var声明的变量会产生变量提升会覆盖上面声明的结果,但是let会在当前产生一个块作用域
2.循环遍历泄漏为全局变量
for (var i = 0; i < 10; i++) { console.log(i); } console.log(i); //10for (let j = 0; j < 10; j++) { console.log(j); } console.log(j); //j is not defined


    推荐阅读