zoukankan      html  css  js  c++  java
  • js之作用域

     

    JavaScript的函数是在局部作用域内运行的,在局部作用域内运行的函数体可以访问其外层的(可能是全局作用域)的变量和函数。JavaScript的作用域为词法作用域,所谓词法作用域是说,其作用域为在定义时(词法分析时)就确定下来的,而并非在执行时确定,如下例:

    var str = "global";
         function scopeTest(){     
              print(str);
              var str = "local";
              print(str);
         }     
        scopeTest();   

    运行结果是什么呢?初学者很可能得出这样的答案:
    global
    local
    而正确的结果应该是:
    undefined
    local

    因为在函数scopeTest的定义中,预先访问了未声明的变量str,然后才对str变量进行初始化,所以第一个print(str)会返回undifined错误。那为什么函数这个时候不去访问外部的str变量呢?这是因为,在词法分析结束后,构造作用域链的时候,会将函数内定义的var变量放入该链,因此str在整个函数scopeTest内都是可见的(从函数体的第一行到最后一行),由于str变量本身是未定义的,程序顺序执行,到第一行就会返回未定义,第二行为str赋值,所以第三行的print(str)将返回”local”
    具体来讲:第1行的str(global)在定义时首先被存入作用域链的头部即全局作用域;
    在调用scopeTest时,js解释器生成1个调用对象(call object),并将scopeTest内通过var定义的str设为它的一个属性,然后再把这个对象加到作用域链的最前端,通俗理解即具有最优先的访问权。
    在访问str时,首先查询scopeTest的调用对象,如果从中没找到str则查询仅挨该对象的上一个作用域,以此类推直至全局作用域。
    此例中从调用对象中即可查到str,因此全局对象中的str被覆盖:第3行,调用对象中有str定义但未赋值,因此为undefined;第4行,赋值;第5行,有值,所以是local。
         var str = "global";   
         function scopeTest(){      
             print(str);    //global  
         }     
        scopeTest();   
    为什么这里是global?因为scopeTest的调用对象里没有str的定义,因此必须查询全局作用域,所以得出global。
    为什么“词法作用域”的效果是“函数在定义它的作用域中执行,而不是执行它的环境”?那是因为函数始终只能沿着定义它时就确定了的“作用域链”逐级访问变量,与外界执行环境无关:
           var str = "global";     
           function scopeTest(){         
                alert(str);      
           }  
           (function(){     
               var str="aaa";     
                scopeTest();//global
         })();

  • 相关阅读:
    wgcloud问题处理——被监控的客户机掉线
    WGCLOUD下发指令时候如何屏蔽linux敏感字符
    WGCLOUD左侧菜单如何保持展开状态
    zerotier 实现 minecraft 局域网联机 | 我的世界联机教程 | minecraft联机
    [ UVa 12096 详解] The Set Stack Computer 集合栈计算机 | map、set、vector、stack、宏函数等知识点简单应用
    [ Uva 101 详解 ] the block problem 木块问题
    Python操作数据库基本操作-sqlalchemy
    统计目录下程序源程序的行数之和-Python
    凯撒密码C++实现
    【题解】[AGC036F] Square Constraints
  • 原文地址:https://www.cnblogs.com/lucky323ping/p/3501647.html
Copyright © 2011-2022 走看看