js 作用域 / 预解析 / 闭包

JavaScript 作用域

在 JavaScript 中, 对象和函数同样也是变量。

作用域为变量,对象,函数的集合。

1.1 全局作用域

 作用 <script>标签内 / 单个独立js文件的代码环境

 变量在函数外声明属于全局作用域。  

 全局变量:在任意位置都可以访问。

        

1.2 局部 /(函数)作用域

      作用在函数内的代码环境

      变量在函数内声明,变量属于局部作用域。  

      局部变量:只能在函数内部访问。

      因为局部变量只作用于函数内,所以不同的函数可以使用相同变量名。

      局部变量在函数开始执行时创建,函数执行完后局部变量会自动销毁

变量的生命周期

开始于变量声明时

全局变量销毁在页面关闭时

局部变量销毁在函数执行后

函数参数

函数参数作用在函数域中故属于局部作用域

作用域链

内层域如果没有所需变量则逐层向上层域查找直至找到后使用;

如果上级域重复包含所需变量则就近域取值;

此过程表现为链。

function a () {
  let a = 1
  function b () {
    // let a = 2
    function c () {
      // let a = 3
      console.log(a)
    }
    c()
  }
  b()
}
a()

预解析

JavaScript 代码是由浏览器中的 js 解析器来执行的。

js解析器在运行js代码的时候分为两步:预解析和代码执行预解析会把 变量和函数 的声明放在代码执行之前执行完成。

// 1.变量域解析 将a提前声明初始值为undefind
console.log(n)
var n = 10

/*
 2. 函数域解析 
    function声明的函数可以提升到调用函数前
    匿名函数发生的变量提升,不可以提前调用函数
*/

// 函数以声明可以调用
Lookb()
function Lookb () {
  console.log('b')
}

// Cannot access 'lookC' before initialization 初始化前无法访问“lookC”
// 在此匿名函数发生的变量预解析,lookC变量被提前声明默认值为undefind,undefind()无法调用函数
lookC()
let lookC = function () {
  console.log('C')
}

闭包

<script>
  // 闭包将局部变量长期保存,防止污染全局变量
  //  下面例子中体现了闭包:通过外层函数作用域保存局部变量a,通过内存函数引用修改外层局部变量a
  //  外层函数返回内侧函数aJJson,实现了外层局部变量a的持久化。
  //  当不需要此闭包的变量时可以将保存内层函数的变量aJJson 赋值为Null


  // 函数执行后a会销毁,所以每次调用都是9
  /* function aJJ () {
    let a = 10
    a--
    console.log(a)
  } */

  function aJJ () {
    let a = 10
    function aJJson () {
      a--
      console.log(a)
    }
    return aJJson
  }

  let aJJson = aJJ()
  // 不需要该闭包则赋值为null
  // aJJson = null
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值