js 函数提升和变量提升 函数提升比变量提升优先级高! 词法分析 总结

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

总结:

词法分析

词法分析方法:

js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤:

  • 分析参数
  • 再分析变量的声明
  • 分析函数说明

具体步骤如下:

  • 函数在运行的瞬间,生成一个活动对象(Active Object),简称AO
  • 分析参数
  1. 函数接收形式参数,添加到AO的属性,并且这个时候值为undefine,例如AO.age=undefine
  2. 接收实参,添加到AO的属性,覆盖之前的undefine
  • 分析变量声明,如var age;或var age=23;
  1. 如果上一步分析参数中AO还没有age属性,则添加AO属性为undefine,即AO.age=undefine
  2. 如果AO上面已经有age属性了,则不作任何修改
  • 分析函数的声明,如果有function age(){}

把函数赋给AO.age ,覆盖上一步分析的值

代码例子1

这样我们先通过一段代码来理解词法分析:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        console.log(age);
        var age = 27;
        console.log(age);
        function age() {}
        console.log(age);
    }
    t1(3);
</script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

词法分析阶段:

 等价于:

<script>
    function t1(age) {
        var age=     function () {}
        console.log(age);
        var age = 27;
        console.log(age);
   
        console.log(age);
    }
    t1(3);
</script>

  

  • 首先形成Active Object即AO对象
  • 第一步:分析形式参数

AO.age = undefine

传入实参即对AO.age=undefine进行覆盖:

AO.age = 3

  • 第二步:分析局部变量

存在var age = 27;

这个时候遵循如果AO.age存在值则不作任何修改,按照第一步分析的最后结果AO.age = 3,所以这里不作任何修改即:

AO.age = 3

  • 第三步:分析函数的声明,

因为函数中存在function age(){}函数

所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 3即:

AO.age = function age(){}

执行阶段

执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){},所以会打印:

function age(){}

var age=27;给age赋值27

到第二个console.log(age)这个时候age已经重新被赋值27,所以这个时候会打印:

27

function age() 并没有调用所以并不会执行

到第三个console.log(age)这个时候age的值并没有被再次修改,所以这个时候会打印:

27

运行js查看结果如下与我们分析的完全相符:

 js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

代码例子2

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        var age;
        console.log(age);
        var age = 23;
        console.log(age);
        function age() {}
        console.log(age);
    }
    t1(22)
</script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

和上面的词法分析过程一样

词法分析阶段:

等价于:

<script>
    function t1(age) {
        var age=  function () {};
        console.log(age);
        var age = 23;
        console.log(age);
      
        console.log(age);
    }
    t1(22)
</script>

  

  • 首先形成Active Object即AO对象
  • 第一步:分析形式参数

AO.age = undefine

传入实参即对AO.age=undefine进行覆盖:

AO.age = 22

 

  • 第二步:分析局部变量

第一步中最后得到AO.age = 22

所以这里var age;以及var age =23 ,因为AO.age属性已经存在值,所以这个时候遵循如果存在则不作任何修改,即:

AO.age = 22

  • 第三步:分析函数的声明,

因为函数中存在function age(){}函数

所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 22即:

AO.age = function age(){}

执行阶段

执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){},所以会打印:

function age(){}

var age=23;给age赋值23

到第二个console.log(age)这个时候age已经重新被赋值23,所以这个时候会打印:

23

function age() 并没有调用所以并不会执行

到第三个console.log(age)这个时候age的值并没有被再次修改,所以这个时候会打印:

23

运行js查看结果如下与我们分析的完全相符:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

代码例子3

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        var age;
        console.log(age);
        age = 23;
        console.log(age);
        function age() {
            console.log(age);
        }
        age();
        console.log(age)
    }
    t1(22)
</script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

词法分析阶段:

等价于:

<script>
    function t1(age) {
        var age=  function age() {  //函数表达式
            console.log(age);
        };
        console.log(age); //输出age函数
        age = 23;    
        console.log(age);   //age是变量
      
        age();  //报错
        console.log(age)
    }
    t1(22)
</script>

  

  • 首先形成Active Object即AO对象
  • 第一步:分析形式参数

AO.age = undefine

传入实参即对AO.age=undefine进行覆盖:

AO.age = 22

 

  • 第二步:分析局部变量

第一步中最后得到AO.age = 22,所以这里遵循,如果AO.age存在值则不作任何修改即:

AO.age = 22

  • 第三步:分析函数的声明

因为函数中存在function age(){console.log(age)}函数

所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 22即:

AO.age = function age(){console.log(age)}

 

执行阶段

执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){console.log(age)},所以会打印:

function age(){console.log(age)}

 

age = 23,这个时候会覆盖原来的function age(){console.log(age)},所以第二个console.log(age)会打印:

23

function age() 是一个函数表达式,所以不会做任何操作

age() 这个时候的age还是23,并不是函数表达式,所以这里会报错

运行js查看结果如下与我们分析的完全相符:

 js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

这里的提示错误确实也是说age不是一个函数

代码例子4

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        var age=function  age() {
            console.log(age);
        }
; console.log(age); 
age();
console.log(age);
}
t1(23) </script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

词法分析阶段:

  • 首先形成Active Object即AO对象
  • 第一步:分析形式参数

AO.age = undefine

传入实参即对AO.age=undefine进行覆盖:

AO.age = 23

  • 第二步:分析局部变量

第一步中最后得到AO.age = 23,所以这里遵循,如果AO.age存在值则不作任何修改即:

AO.age = 23

  • 第三步:分析函数的声明

因为函数中存在function age(){console.log(age)}函数

所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 23即:

AO.age = function age(){console.log(age)}

执行阶段

执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){console.log(age)},所以会打印:

function age(){console.log(age)}

 

function age() 是一个函数表达式,所以不会做任何操作

 

age()这个时候age是一个函数表达式,这里会执行function age(){console.log(age)},这个时候函数里console.log(age),age没有被修改所以还是function age(){console.log(age)},即打印:

function age(){console.log(age)}

 

最后一个console.log(age)这里的age没有被修改还是function age(){console.log(age)},所以会打印:

function age(){console.log(age)}

运行js查看结果如下与我们分析的完全相符:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

代码例子5:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        console.log(age);   //23
        var age = function () {
            console.log(age)
        }
        age();   //函数
        console.log(age);  //函数
    }
    t1(23);
</script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

词法分析阶段:

  • 首先形成Active Object即AO对象
  • 第一步:分析形式参数

AO.age = undefine

传入实参即对AO.age=undefine进行覆盖:

AO.age = 23

 

  • 第二步:分析局部变量

第一步中最后得到AO.age = 23,所以这里遵循,如果AO.age存在值则不作任何修改即:

AO.age = 23

  • 第三步:分析函数的声明

这里并没有函数声明表达式

所以最后分析的结果是:

AO.age = 23

执行阶段

执行t1函数,到console.log(age)时,词法分析的最后AO.age=23

所以第一个console.log(age)会打印

23

var age = function () {console.log(age)},这里将var = 23进行覆盖这个时候age是一个函数表达式

age() 正好调用function () {console.log(age)},这个时候这个函数里的console.log(age),age并没有修改还是一个函数表达式,所以会打印

function () {console.log(age)}

最后一个console.log(age)还是打印:

function () {console.log(age)}

运行js查看结果如下与我们分析的完全相符:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

代码例子6:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        console.log(age);
        var age = function age() {
            console.log(age);
        }
        age();
        console.log(age);
    }
    t1(23);
</script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

代码例子6和代码例子5的分析基本一样,结果也是一样:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

总结

总之,按照上述最开始写的方法分析,都能分析出结果来

所有的努力都值得期许,每一份梦想都应该灌溉!

词法分析

词法分析方法:

js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤:

  • 分析参数
  • 再分析变量的声明
  • 分析函数说明

具体步骤如下:

  • 函数在运行的瞬间,生成一个活动对象(Active Object),简称AO
  • 分析参数
  1. 函数接收形式参数,添加到AO的属性,并且这个时候值为undefine,例如AO.age=undefine
  2. 接收实参,添加到AO的属性,覆盖之前的undefine
  • 分析变量声明,如var age;或var age=23;
  1. 如果上一步分析参数中AO还没有age属性,则添加AO属性为undefine,即AO.age=undefine
  2. 如果AO上面已经有age属性了,则不作任何修改
  • 分析函数的声明,如果有function age(){}

把函数赋给AO.age ,覆盖上一步分析的值

代码例子1

这样我们先通过一段代码来理解词法分析:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        console.log(age);
        var age = 27;
        console.log(age);
        function age() {}
        console.log(age);
    }
    t1(3);
</script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

词法分析阶段:

 等价于:

<script>
    function t1(age) {
        var age=     function () {}
        console.log(age);
        var age = 27;
        console.log(age);
   
        console.log(age);
    }
    t1(3);
</script>

  

  • 首先形成Active Object即AO对象
  • 第一步:分析形式参数

AO.age = undefine

传入实参即对AO.age=undefine进行覆盖:

AO.age = 3

  • 第二步:分析局部变量

存在var age = 27;

这个时候遵循如果AO.age存在值则不作任何修改,按照第一步分析的最后结果AO.age = 3,所以这里不作任何修改即:

AO.age = 3

  • 第三步:分析函数的声明,

因为函数中存在function age(){}函数

所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 3即:

AO.age = function age(){}

执行阶段

执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){},所以会打印:

function age(){}

var age=27;给age赋值27

到第二个console.log(age)这个时候age已经重新被赋值27,所以这个时候会打印:

27

function age() 并没有调用所以并不会执行

到第三个console.log(age)这个时候age的值并没有被再次修改,所以这个时候会打印:

27

运行js查看结果如下与我们分析的完全相符:

 js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

代码例子2

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        var age;
        console.log(age);
        var age = 23;
        console.log(age);
        function age() {}
        console.log(age);
    }
    t1(22)
</script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

和上面的词法分析过程一样

词法分析阶段:

等价于:

<script>
    function t1(age) {
        var age=  function () {};
        console.log(age);
        var age = 23;
        console.log(age);
      
        console.log(age);
    }
    t1(22)
</script>

  

  • 首先形成Active Object即AO对象
  • 第一步:分析形式参数

AO.age = undefine

传入实参即对AO.age=undefine进行覆盖:

AO.age = 22

 

  • 第二步:分析局部变量

第一步中最后得到AO.age = 22

所以这里var age;以及var age =23 ,因为AO.age属性已经存在值,所以这个时候遵循如果存在则不作任何修改,即:

AO.age = 22

  • 第三步:分析函数的声明,

因为函数中存在function age(){}函数

所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 22即:

AO.age = function age(){}

执行阶段

执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){},所以会打印:

function age(){}

var age=23;给age赋值23

到第二个console.log(age)这个时候age已经重新被赋值23,所以这个时候会打印:

23

function age() 并没有调用所以并不会执行

到第三个console.log(age)这个时候age的值并没有被再次修改,所以这个时候会打印:

23

运行js查看结果如下与我们分析的完全相符:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

代码例子3

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        var age;
        console.log(age);
        age = 23;
        console.log(age);
        function age() {
            console.log(age);
        }
        age();
        console.log(age)
    }
    t1(22)
</script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

词法分析阶段:

等价于:

<script>
    function t1(age) {
        var age=  function age() {  //函数表达式
            console.log(age);
        };
        console.log(age); //输出age函数
        age = 23;    
        console.log(age);   //age是变量
      
        age();  //报错
        console.log(age)
    }
    t1(22)
</script>

  

  • 首先形成Active Object即AO对象
  • 第一步:分析形式参数

AO.age = undefine

传入实参即对AO.age=undefine进行覆盖:

AO.age = 22

 

  • 第二步:分析局部变量

第一步中最后得到AO.age = 22,所以这里遵循,如果AO.age存在值则不作任何修改即:

AO.age = 22

  • 第三步:分析函数的声明

因为函数中存在function age(){console.log(age)}函数

所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 22即:

AO.age = function age(){console.log(age)}

 

执行阶段

执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){console.log(age)},所以会打印:

function age(){console.log(age)}

 

age = 23,这个时候会覆盖原来的function age(){console.log(age)},所以第二个console.log(age)会打印:

23

function age() 是一个函数表达式,所以不会做任何操作

age() 这个时候的age还是23,并不是函数表达式,所以这里会报错

运行js查看结果如下与我们分析的完全相符:

 js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

这里的提示错误确实也是说age不是一个函数

代码例子4

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        var age=function  age() {
            console.log(age);
        }
; console.log(age); 
age();
console.log(age);
}
t1(23) </script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

词法分析阶段:

  • 首先形成Active Object即AO对象
  • 第一步:分析形式参数

AO.age = undefine

传入实参即对AO.age=undefine进行覆盖:

AO.age = 23

  • 第二步:分析局部变量

第一步中最后得到AO.age = 23,所以这里遵循,如果AO.age存在值则不作任何修改即:

AO.age = 23

  • 第三步:分析函数的声明

因为函数中存在function age(){console.log(age)}函数

所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 23即:

AO.age = function age(){console.log(age)}

执行阶段

执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){console.log(age)},所以会打印:

function age(){console.log(age)}

 

function age() 是一个函数表达式,所以不会做任何操作

 

age()这个时候age是一个函数表达式,这里会执行function age(){console.log(age)},这个时候函数里console.log(age),age没有被修改所以还是function age(){console.log(age)},即打印:

function age(){console.log(age)}

 

最后一个console.log(age)这里的age没有被修改还是function age(){console.log(age)},所以会打印:

function age(){console.log(age)}

运行js查看结果如下与我们分析的完全相符:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

代码例子5:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        console.log(age);   //23
        var age = function () {
            console.log(age)
        }
        age();   //函数
        console.log(age);  //函数
    }
    t1(23);
</script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

词法分析阶段:

  • 首先形成Active Object即AO对象
  • 第一步:分析形式参数

AO.age = undefine

传入实参即对AO.age=undefine进行覆盖:

AO.age = 23

 

  • 第二步:分析局部变量

第一步中最后得到AO.age = 23,所以这里遵循,如果AO.age存在值则不作任何修改即:

AO.age = 23

  • 第三步:分析函数的声明

这里并没有函数声明表达式

所以最后分析的结果是:

AO.age = 23

执行阶段

执行t1函数,到console.log(age)时,词法分析的最后AO.age=23

所以第一个console.log(age)会打印

23

var age = function () {console.log(age)},这里将var = 23进行覆盖这个时候age是一个函数表达式

age() 正好调用function () {console.log(age)},这个时候这个函数里的console.log(age),age并没有修改还是一个函数表达式,所以会打印

function () {console.log(age)}

最后一个console.log(age)还是打印:

function () {console.log(age)}

运行js查看结果如下与我们分析的完全相符:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

代码例子6:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结
<script>
    function t1(age) {
        console.log(age);
        var age = function age() {
            console.log(age);
        }
        age();
        console.log(age);
    }
    t1(23);
</script>
js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

代码例子6和代码例子5的分析基本一样,结果也是一样:

js 函数提升和变量提升
函数提升比变量提升优先级高!
词法分析
总结

总结

总之,按照上述最开始写的方法分析,都能分析出结果来