JavaScript全局作用域函数作用域和块级作用域的区别
Posted 奥特曼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 声明的可以访问到,我们到断点去看一下
我们发现用let 定义的变量 放到了Block区块中,而var声明的变量放在了Global全局当中,所以说var在块级作用域下我们可以进行访问
查了资料看到MDN说
个人理解就是var定义的变量 不管在哪定义的,都会放到window下 所以用的都是同一个作用域。
接下来看let中在{ }定义的变量
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); //10
for (let j = 0; j < 10; j++) {
console.log(j);
}
console.log(j); //j is not defined
以上是关于JavaScript全局作用域函数作用域和块级作用域的区别的主要内容,如果未能解决你的问题,请参考以下文章