zoukankan      html  css  js  c++  java
  • Javascript 笔记与总结(1-2)词法分析

    词法分析,按顺序分析 3 样:

    第 1 步:先分析参数

    第 2 步:再分析变量声明

    第 3 步:再分析函数声明

    一个函数能使用的局部变量,就从上面 3 步分析而来。

    具体步骤:

    0:函数运行前的瞬间,生成 Active Object(活动对象)

    1: 1.1 把函数声明的参数,形成 AO (Active Object)的属性,值全是 undefined,

      1.2 接受实参形成 AO 相应属性的值

    2:分析变量声明,如 var age,如果 AO 上已经有 age 属性,则不作任何影响;如果 AO 上还没有 age 属性,则添加 AO 属性,但此时没赋值,值是 undefined

    3:分析函数声明,如 function foo(){},则把函数赋给 AO.foo 属性

    注:如果此前 foo 属性已经存在,则会被覆盖成函数

    例1

    <script>
        function a(b){
            alert(b);
            function b(){
                alert(b);
            }
            b();
        }
        a(1);
    </script>

    【答案】:两次弹出

    function b(){

    alert(b);

    }

    【分析】

    分析期:

     0. AO = {}

    1.

      1.1 分析参数 AO = {b:undefined}

      1.2 接收参数 AO = {b:1}

    2. 分析 var 声明,此处函数没有 var

    3. 分析函数声明,AO = {b:function(){alert(b);}}

    执行期:

    alert(b);   // function

    b();  // 由作用域寻找到 a 函数中的 b,即 function,alert() 出来

    例2

    <script>
        function t(age){
            alert(age);
        }
        t(5); //5
        t(); //undefined
    </script>

    【分析】

    词法分析过程:

    AO{ age = undefined }

    运行过程:

    t(5); → AO.age = 5; alert(AO.age); //5

    t(); → AO.age = undefined; //AO.age 没有得到赋值,还是 undefined

    例3

    <script>
        function t(age){
            var age = 10;
            alert(age);
        }
        t(5);
    </script>

    弹出 10。

    【分析】

    词法分析过程:

    0. 形成AO = {}

    1.

      1.1 分析形参 AO = {age:undefined}

          1.2 接收形参:AO = {age:5}

    2. 分析 var age,发现 AO 已有 age 属性,不做任何影响

    执行过程:

    AO.age = 10

    alert(age); //10

    例4(和例1 做对比):

    <script>
        function t(greet){
            var greet = 'hello';
            alert(greet);
            function greet(){
            }
            alert(greet);
        }
        t(null);
    </script>

    弹出两次 'hello'

    【分析】

    词法分析过程:

    0. AO = {}

    1. 

      1.1 分析形参:AO = {greet = undefined}  

      1.2 接收形参:AO = {greet:null}

    2. 分析 greet 变量声明,AO 已经有 greet 属性,因此不做任何影响

    3. 分析 greet 函数声明,AO.greet = function(){},被覆盖成函数

    执行过程:

    greet = 'hello';

    alert(greet);

    alert(greet);

    【再分析】

    var greet = 'hello';

    这一句要当成两句看(两次执行):① 分析期的 var 声明过程 ② 运行期的 赋值 过程

    由于在运行期被赋值成了 'hello',因此两次 alert 弹出的都是 'hello'

    如果去掉该句(则和例 1 一样)或者改为 var greet; ,则弹出两次

    function greet(){}

    例5 

    <script>
    function a(b){
        alert(b);
        b = function (){
            alert(b);
        }
        b();
    }
    a(1);
    </script>

    分别弹出 1 和 function (){alert(b)}

    【词法分析过程】:

    0:AO = {}

    1.分析参数 AO = {b:undefined}  → {b:1}

    2.分析 var 声明,没有

    3.分析函数声明,没有

    注:b = function(){alert(b)} ,是一个赋值过程,在执行器才起作用

    【执行过程】:

    alert(b);   //b = 1

    b = function(){

      alert(b);    //往上找,找到b = function(){}

    }

    b(); // funtion

    【函数声明 与 函数表达式】

    函数可以赋值给变量,可以作为参数来传递

    function t1(){
    }

    t2 = function(){
    }

    t1 是函数声明,虽然全局内也得到一个 t1 变量,值是 function;

    t2 只是一个赋值过程,值是右侧的表达式的返回结果,即函数

    因此 t1 和 t2 两种方式在词法分析时,有着本质区别:前者在词法分析阶段就发挥作用,后者在函数运行阶段才发挥作用

    例如:

    (function(window,undefined){
    })(window)

    这是 jQuery 的最外层代码

    【分析】

    (function(window,undefined){})

    这是内层表达式,返回值是函数,包在小括号里,当成表达式来执行

    (function(window,undefined){})(window)

    立即调用

    而内层函数又没有起名字,成为匿名函数

    这种手法,匿名函数,立即执行,不污染全局,称为 立即执行匿名函数表达式

    传 window 是为了速度,不传 undefined 是为了防止外界对 undefined 的污染(在 IE 、FF 低版本中,undefined 可以重新赋值,例如 undefined = 3;)

    【作用域链】

    指函数由内到外,产生的 AO 链

    词法分析时由外至内,分析 AO 链;执行时由内到外,寻找 AO 链

    更多词法作用域文章:JavaScript的词法作用域

  • 相关阅读:
    javaScript
    CSS
    HTML
    折纸 (模拟)
    不等式(数学)
    周期串查询
    大集训模拟赛十一
    大假期集训模拟赛十
    P1631 序列合并
    KMP(烤馍片)算法
  • 原文地址:https://www.cnblogs.com/dee0912/p/4396798.html
Copyright © 2011-2022 走看看