JavaScript 中的作用域预解析以及变量提升
Posted UI前端小菜一名
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 中的作用域预解析以及变量提升相关的知识,希望对你有一定的参考价值。
javascript 中的作用域、预解析以及变量提升
作用域:变量的作用范围
-
局部作用域:函数内部
在局部作用域声明的变量称为局部变量,局部变量只能在当前函数内部使用
1)函数在执行的时候会在内存中开辟新空间
2)当执行完毕函数之后,会关闭作用域空间(变量被销毁)
注意:形参也是局部变量
function fn() { let b = 5 // 局部访问 变量 b console.log(b) // 5 } fn() // 全局访问 变量 b console.log(b) // 访问不存在的变量,报错
在控制台打印得到如下结果
-
全局作用域:函数外部
1)在全局作用域声明的变量是全局变量,全局变量可以在任何地方使用
2)因为全局变量可以任何地方使用,所以要特别关注局部变量
let a = 2 function fn() { // 局部访问 变量 a console.log(a) // 2 } fn() // 全局访问 变量 a console.log(a) // 2
在控制台打印得到如下结果
函数内部之所以能够访问到变量 a ,是因为有一个作用链,函数内部访问一个变量会先在自己的作用域内找,找不到会向上级作用域找,找不到就会报错
例如 如下代码
(找不到报错的情况)
function fn() { function fn1() { function fn2() { // 局部访问 变量 a console.log(a) // 2 } fn2() } fn1() } fn()
控制台打印
(全局变量局部访问的情况)
let a = 'hello javascript'
function fn() {
function fn1() {
function fn2() {
// 局部访问 变量 a
console.log(a) // hello javascript
}
fn2()
}
fn1()
}
fn()
控制台打印
-
块级作用域:类似局部作用域
1)用 {} 包裹一块
2)let声明变量具有块级作用域,var声明变量不具有块级作用域
例如
(以字面量对象为例)
let obj = { uname: '法外狂徒-张三', age: 68 }
想要访问这个对象里面的属性必须通过
obj.属性
,而不能直接访问
预解析
预解析:在代码执行之前把变量和函数会提前解析到当前作用域的最前面
任何作用域在执行之前都要预解析 (函数优于变量)
变量:带有声明的变量,只定义不赋值
1)变量在声明之前被访问,变量的值为 undefined
函数:带有名字的函数,只定义不调用
1)函数优于变量
console.log(a) // undefined
fn() // hello javascript
function fn() {
console.log('hello javascript')
}
var a = 2
代码是自上而下执行,但是在代码执行前会先进行代码的预解析,把变量以及函数 声明 提升到当前作用域的最前面,如上代码,console.log(a)
会打印 undefined
但是,注意!!!注意!!!
变量必须是 var 声明的才可以,如果是 let 声明的变量会报错
图 (var 声明的 a)
图 (let 声明的 a)
变量提升
预解析会引起变量的提升
变量不声明就输出会报错
console.log(a) // 报错
控制台打印
用 var 声明
console.log(a) // undefined
var a = 'hello javascript'
控制台打印 undefined ,我们知道变量定义不赋值会输出 undefined,说明变量已经存在并且提升了,但是只提升了声明没有提升赋值,所以打印 undefined ,如果没有提升的话,就会像上面一样在执行 console.log(a)
的时候直接报错
结论:var 存在变量提升
用 let 声明
console.log(a) // 报错
let a = 'hello javascript'
结论:let 不存在变量提升
补充:
申明变量:let \\ var \\ const
1)let 声明的变量不在window内
2)var 声明的变量相当于给window添加了个属性,let不会
3)var 声明的变量不具有块级作用域,let具有块级作用域
4)var 可以重复声明,let只能声明一次
5)const 用来定义常量,不可以改值
6)const 定义的常量必须初始化有值,let可以不设置值
建议:常量名字因为是不可以改动的值,所以常量名建议用大写,一般用于定义固定不变的值
以上是关于JavaScript 中的作用域预解析以及变量提升的主要内容,如果未能解决你的问题,请参考以下文章