JavaScript-变量的作用域闭包预解析

Posted 速速逃离月球表面

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript-变量的作用域闭包预解析相关的知识,希望对你有一定的参考价值。

变量的作用域

通常来说,指一段代码中所用到的名字的可用性的代码范围就是该名字的作用域。(代码名字(变量)在某个范围内起作用和效果)
作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

javascript(es6前)中的作用域分为两种:

  • 全局作用域:作用于整个script标签或者是一个单独的js文件
  • 局部作用域(函数作用域):代码名字只在函数内部起作用和效果,跟函数有关系。

JS没有块级作用域(在ES6之前):块作用域由 { } 包括,比如 if { } ; for { } 。因此 if 和 for 中定义的变量在外侧可以随意使用

if(true){
  var num = 123;
  console.log(num); //123
}
console.log(num);   //123

全局变量:(在函数外部定义的变量)

  • 在代码任何位置都能使用
  • 在全局作用域下var声明的变量
  • 特殊情况下,在函数内不使用var声明的变量也是全局变量(不建议使用)

局部变量:(在函数内部定义的变量)

  • 只能在函数内部使用
  • 在函数内部var声明的变量
  • 函数的形参实际上就是局部变量

全局变量和局部变量的区别

  • 全局:任何地方都能使用,只有在浏览器关闭时才会被销毁,比较占内存
  • 局部:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块结束运行后,会被销毁,更节省内存空间

作用域链:采取就近原则来查找变量最终的值

  • 只要是代码,就至少有一个作用域
  • 写在函数内部的局部作用域
  • 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
  • 根据内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链

闭包

所谓“闭包”指的就是有权访问另一个函数作用域内变量(局部变量)的函数

主要用途:

  • 可以在函数外部读取函数内部的变量
  • 可以让变量的值始终保持在内存中

注意:由于闭包会使得函数的变量一直被保存在内存中,内存消耗很大,所以闭包的滥用可能会降低程序的处理速度,造成内存消耗等问题

一句话概括:闭包就是能够读取其他函数内部变量的函数,或者子函数在外调用,子函数所在的父函数的作用域不会被释放

预解析

JS引擎/解释器运行JS代码时分为两步:预解析和代码执行

  • 预解析:执行代码前,JS引擎会把JS里所有varfunction声明的变量提升到当前作用域的最前面
  • 代码执行:按照书写顺序从上往下执行

预解析只发生在通过 var 定义的变量和 function 上。学习预解析就能知道为什么在变量声明之前访问变量的值是 undefined,为什么在函数声明之前就可以调用函数。

预解析也叫变量、函数提升。

  • 变量预解析(变量提升):就是把所有的变量声明提升到当前作用域最前面,不提升赋值操作
  • 函数预解析(函数提升):就是把所有的函数声明提升到当前作用域的最前面,不调用函数

以上是关于JavaScript-变量的作用域闭包预解析的主要内容,如果未能解决你的问题,请参考以下文章

javascript里面的闭包,作用域,预解析

预编译作用域链和闭包理解

JavaScript函数函数进阶作用域及预解析

JavaScript必须了解的知识点总结。

JavaScript必须了解的知识点总结。

JavaScript 闭包全方位解析