变量提升

139 阅读3分钟

变量提升(预解析)

一、JavaScript引擎

JavaScript引擎的主要作用是,读取JavaScript代码进行处理和运行。

JavaScript引擎(JavaScript解释器),在执行JS代码之前 会先在当前作用域中进行预解析阶段,然后再从上到下开始逐行执行JS代码。

JS中代码执行分为两个步骤:

1.预解析 先全盘扫描当前作用域中的所有声明的变量,进行预先的分析和处理

2.执行 从上到下开始 逐行解释并运行JS代码

JS代码在运行之前,先解析当前作用域中的所有代码,获取所有被声明的变量进行预处理。

二、变量提升(预解析)

在JS代码执行之前,会把当前作用域中所有带var和带function关键字的变量 进行提前的声明和定义(赋值)。

变量提升中普通变量和函数变量

在变量提升阶段:

对于带var的普通变量 会被提前声明并被赋值为默认值undefined

对于带function的函数变量 会被提前声明并被赋值为当前函数本身

  console.log(num) // undefined
  var num = 100 // 代码执行的时候 才会进行赋值操作

用var定义的变量,在定义变量之前使用变量 输出得是变量的默认值undefined

  console.log(fe) // function fe() { console.log('fe') }
  fe() // 'fe'
  function fe() {
    console.log('fe')
  }

用function定义的函数变量,在定义之前使用,输出的函数是被提前定义好的函数本身,所以我们可以在函数定义之前就来使用函数。

按照正常的思维逻辑,我们本应该是在定义了变量之后才可以使用变量。但在JS中由于存在变量提升的原因 导致出现了上面👆的现象。

变量提升结束之后,代码开始从上到下逐行解释并运行

三、作用域(栈内存)

作用域(栈内存),供JS代码执行的环境,也是用来保存基本数据类型的值。

JS中的作用域

全局作用域(window) 当打开页面时,浏览器为了执行全局中的所有代码 而提供的JS执行的环境

函数作用域(私有作用域) 当函数执行的时候,为了执行函数体里的代码,而提供的JS执行的环境

块级作用域(私有作用域) 在代码块中{},使用ES6提供的let const 形成的作用域

只要是想执行JS代码 就需要提供一个作用域(栈内存)让代码在里面执行,比如 你想要踢足球 你就需要有一个能踢足球的活动场地(所谓足球场)。

全局指的是 页面中的整个script

<script>
  // 全局中的代码
</script>

全局变量和私有变量

全局变量 在全局作用域中声明的变量(全局变量参加的是全局中的变量提升)

私有变量 在私有作用域中声明的变量(私有变量参加的是私有作用域中的变量提升)

  var boy = 'boy' // 全局变量

  function fn(num) { // num 形参变量也属于函数中的私有变量
    var girl = 'girl' // girl 函数中的私有变量
  }

变量提升只发生在当前作用域中

当打开页面的时候,最先进行的是全局作用域中的变量提升。 当函数执行的时候,进行的是函数作用域中的变量提升。

console.log(a)
var a = 'java'

function fn() {
  console.log(s)
  var s = 'script'
}