js- 为什么会发生变量提升

剖析

js代码是一行一行执行的,但是在执行前,他也是有一起准备阶段的

  • js的作用域是静态的,他在函数定义的时候,就决定了他的作用域(函数,变量可访问的范围)
  • 当我们执行函数的时候,会产生执行期上下文EC
  • 上下文是分为全局上下文,和函数上下文。里面有变量对象,作用域链,this指向
  • 执行上下文的周期有两个阶段,创建阶段 (预编译,也就是变量提升),代码指向阶段

那到这里就明白了,变量提升其实就是预编译的一些操作

那预编译的操作步骤是哪些呢,下面是函数预编译过程?

  • 创建AO对象 AO{}
  • 找形参和变量声明,将形参和变量当做AO的属性,值是undefined
  • 实参形参相统一
  • 在函数体内找函数声明,赋值函数体
 function fn(a, c) {
        console.log(a); //  function a(){}
        var a = 555
        console.log(a) // 555
        console.log(c) // function c (){}
        function a() {
        }
        console.log(b) // undefined
        console.log(d) // undefined
        if (false) {
            var d = 1
        }
        var b = function () {

        }
        console.log(b) // function (){}
        function c() {

        }
        console.log(c) // function c (){}
    }
    fn(1, 2)
    // AO: {
    //     a: undefined // 1 |function a
    //     c: undefined // 2  | function c 
    //     d: undefined
    //     b: undefined
    // }
复制代码

关于let和var的一些问题


console.log(x) // undefined
var x = 1

复制代码
  • var 声明会在代码执行之前就将「创建变量,并将其初始化为 undefined」。这就解释了为什么在 var x = 1 之前 console.log(x) 会得到 undefined。

·


console.log(x) // 报错
let x = 1

复制代码
  • 执行 log 时 x 还没「初始化」,所以不能使用(也就是所谓的暂时死区)
  • let 的「创建」过程被提升了,但是初始化没有提升。
  • var 的「创建」和「初始化」都被提升了。
  • function 的「创建」「初始化」和「赋值」都被提升了
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享