JavaScript中的作用域和作用域链


JavaScript的作用域和作用域链

JavaScript的作用域

作用域规定了变量能够被访问的“范围”,离开了这个范围变量便不能访问。

作用域分为:

  • 局部作用域
  • 全局作用域

局部作用域

局部作用域分为函数作用域和块作用域。

函数作用域
  • 在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。
  • 不同函数内部声明的变量无法相互访问
  • 函数的参数是函数作用域内的局部变量
块作用域

JavaScript中使用大括号包裹的代码称为代码块,代码块内部声明的变量外部将有可能无法被访问。

  • let声明的变量会产生块作用域,var不会产生块作用域
  • const声明的常量也会产生块作用域
  • 不同代码块之间的变量无法相互访问

全局作用域

<script>标签和js文件的最外层就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。

  • 在全局作用域中声明的变量,任何其他作用域都可以被访问
  • 为window对象动态添加的属性默认也是全局的
  • 函数中未使用任何关键字声明的变量为全局变量
  • 尽可能少使用全局变量,防止全局变量污染

JavaScript的作用域链

作用域链的本质上是底层的变量查找机制。

  • 函数被执行时,会优先在当前函数作用域查找变量
  • 如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域

总结:

  1. 嵌套关系的作用域串联起来形成了作用域链
  2. 相同作用域链中按照从小到大的规则查找变量
  3. 子作用域能够访问父作用域,父级作用域无法访问子级作用域

JavaScript的闭包

一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域(闭包 = 内层函数 + 内层函数引用的外层函数的变量)。

作用

封闭数据,提供操作,使外部也可以访问函数内部的变量。

闭包的基本格式

function outer(){
    let i = 1
    function fn(){
        console.log(i)
    }
    return fn
}
const fun = outer()
fun() // 返回1
// 外层函数使用内部函数的变量

闭包应用

实现数据的私有,比如统计函数调用的次数。

function fn(){
    let count = 0
    function fun(){
        count++
        console.log(`函数被调用${count}`)
    }
    return fun
}
const ret = fn() 
ret() // 函数被调用1次
ret() // 函数被调用2次
//实现数据私有,无法直接修改count
//问题:内存泄漏,count无法被回收

变量提升

变量提升是JavaScript中比较“奇怪”的现象,它允许变量在被声明之前访问(仅存在于var声明变量)。

注意:let和const声明的变量不存在变量提升。

作用流程

  1. JavaScript会把所有var声明的变量提升到当前作用域的最前面。
  2. 只提升声明,不提升赋值。
console.log(num) // 返回undefined,但不报错
var num = 10
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值