js 变量提升

74 阅读2分钟

1. 什么是变量提升

变量提升就是发生在函数执行前,浏览器会进行一次预编译,在这个阶段浏览器会将所有的 var function 关键字进行变量提升,var在这个阶段是只定义不声明,funnction 是既定义又声明。 (而在这个预定义阶段还会 确定 执行上下文 执行上下文栈,确定this指,确定作用域,作用域链 等其他的)

2.对于变量提升分为以下几种情况

  1. var不带var
  2. 等号左边下的变量提升
  3. 条件判断下的变量提升
  4. 重名问题下的变量提升
  5. 函数形参的变量提升
  6. 非匿名自执行函数的变量提升
2.1带 var 不带var 情况
  • 在全局作用域下,带 var 的情况和不带 var 情况 所定义的变量都是在 Windows 上新增了一个属性
  • 在私有作用域下,带 var不带var 的情况是有所不同的,带有 var的 是在当前作用域进行变量提升,不带var是会先上级作用域查找,如果上级作用域没有找到window 那么就会一直向上查找,直到找到为止。
2.2等号左边的变量提升
  • 普通函数左边的变量提升
  • 匿名函数下带有=的变量提升(只提升=左边的部分)
print()
var print = function() {
    console.log('林一一')
}
print()
/*输出
    Uncaught TypeError: print is not a function
/

思路:同样由于变量提升机制带 var 的 print 是一开始值是 undefined,所以 print() 这时还不是一个函数,所以报出 类型错误TypeError

2.3条件判断下的变量提升
2.4重名问题下的变量提升
  • 带var和function重名的情况下变量提升优先级,函数先执行
  • 变量重名在变量提升阶段会重新定义也就是赋值
2.5函数形参的变量提升
  • 函数的形参也会进行一次变量提升
2.6非匿名自执行函数的变量提升
  • 匿名函数在全局作用域下是不具备函数变量名提升的
  • 匿名函数自执行函数在自己的作用域内具有正常的变量名提升
  • 非匿名自执行函数的函数名在自己的作用域内变量提升,且修改函数名的值无效,这是非匿名函数和普通函数的差别
var a = 10;
(function a(){
    console.log(a)
    a = 20
    console.log(a)
})()
// ƒ a(){a = 20 console.log(a)}  ƒ a(){a = 20 console.log(a)}