<dl id="opymh"></dl>

<div id="opymh"></div>
      <div id="opymh"><tr id="opymh"></tr></div>

        <em id="opymh"><ins id="opymh"><mark id="opymh"></mark></ins></em><sup id="opymh"><menu id="opymh"></menu></sup>

        <em id="opymh"></em>

        <em id="opymh"><ol id="opymh"></ol></em>

              频道栏目
              首页 > 程序开发 > web前端 > HTML/CSS > 正文
              js词法作用域和动态作用域
              2019-02-12 11:21:39           
              收藏   我要投稿

              开篇

              当我们在开始学习任?#25105;?#38376;语言的时候£¬都会接触到变量的概念£¬变量的出现其实是为了解决一个问题£¬为的是存储某些值£¬进而£¬存储某些值的目的是为了在之后对这个?#21040;?#34892;访问或者修改£¬正是这种存储和访?#26102;?#37327;的能力将状态给了程序¡£我们的程序中到处都充斥着对于状态的判断£¬根据不同的状态执行不同的逻辑¡£

              我们试想一下£¬如果没有状态这个概念£¬程序虽然也能够执行一些简单的任务£¬但是它会受到很多的限制£¬所能完成的功能是有限?#39057;模?#20030;个例子£¬没有状态你是如何执行循环语句?没有状态如何更加优雅地使用逻辑结构?

              仔细想想£¬好像是寸步难行£¬当然引入变量后帮我们解决了这个问题¡£

              但是£¬引入变量和状态的概念之后会引起几个问题£º这些变量住在哪里?换句话说£¬它们存储在哪里?最重要的是£¬程序需要它们的时候如何找到它们?

              今天我们就一起学习一下这套存储和查找变量的规则£¬这套规则我们称之为£º作用域¡£

              作用域

              我们来拆解一下这个词语,所谓的“域”我们可以理解为£º范围¡¢区域£¬加上“作用”两个字所要表述的问题就是作用的范围¡¢区域£¬比如国家的行政区域划分是为了便于管理£¬类比到程序源代码中作用域的出现也是为了便于对于变量做管理¡£

              好£¬这里我们简单做一下总结£º

              定义£º作用域是指程序源代码中定义变量的区域¡£ 作用£º作用域规定了如何查找变量£¬也就是?#33539;?#24403;前执行代码对变量的访问权限¡£ 在javaScript中的应用 £ºJavaScript采用词法作用域(lexical scoping)£¬也就是静态作用域¡£

              那什么又是 词法作用域或者静态作用域呢?

              请继续往下看

              静态作用域与动态作用域

              因为javaScript采用的是词法作用域,函数的作用域在函数定义的时候就决定了¡£

              而词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的¡£

              让我们看一个例子来理解词法作用域和动态作用域之间的区别£º

              var value = 1;

              function foo() {

              console.log(value);

              }

              function bar() {

              var value = 2;

              foo();

              }

              bar();

              // 结果是

              上面的代码中£º

              1.我们首先定义了一个value£¬并赋值为1; 2.声明一个函数foo£¬函数的功能是打印 value 这个变量的值; 3.声明一个函数bar£¬函数内部重新创建了一个变量 value 这个变量赋值为2;

              在函数内部执行了 foo() 这个函数; 4.执行 bar() 这个函数

              假设javaScript采用静态作用域£¬让我们分析下执行过程£º

              执行foo函数,首先从 foo 函数内部查找是否有变量 value ,如果没有

              就根据书写的位置£¬查找上面一层的代码£¬我们发现value等于1£¬所以结果会打印 1¡£

              假设javaScript采用动态作用域£¬让我们分析下执行过程£º

              执行foo函数£¬依然是从 foo 函数内部查找是否有局部变量 value¡£如果没有£¬

              就从调用函数的作用域£¬也就是 bar 函数内部查找 value 变量£¬所以结果会打印 2¡£

              上面在区分静态作用于和动态作用域的时候,我们已经说了如果是静态作用域£¬那么函数在书写定义的时候已经?#33539;?#20102;£¬而动态作用域是函数执行过程中才?#33539;?#30340;¡£

              JavaScript采用的是静态作用域£¬所以这个例子的结果是 1¡£

              我们在控制台中输入执行上面的函数£¬检验一下执行结果果然是 1¡£

              动态作用域

              那什么语言是采用的动态的作用域呢 其实bash 就是动态作用域£¬

              我们可以新建一个 scope.bash 文件将下列代码放进去£¬执行一下这个脚本文件£º

              #!/bin/bash

              value=1

              function foo () {

              echo $value;

              }

              function bar () {

              local value=2;

              foo;

              }

              bar

              上面代码运行的结果输出2很好解释£¬虽然在代码最上层定义了 value并赋值为1£¬但是在调用foo函数的时候,在查找 foo 内部没有 value 变量后£¬会在foo 函数执行的环境中继续查找£¬也就是在bar 函数中查找£¬很?#20197;?#25105;们找到了¡£

              思考

              最后£¬让我们看一个¡¶JavaScript权威?#25913;Ï¡?#20013;的例子£º

              // 例1£º

              var scope = "global scope";

              function checkscope(){

              var scope = "local scope";

              function f(){

              return scope;

              }

              return f();

              }

              checkscope();

              // 例2£º

              var scope = "global scope";

              function checkscope(){

              var scope = "local scope";

              function f(){

              return scope;

              }

              return f;

              }

              checkscope()();

              让我们来分析一下上面例1的代码:

              1¡¢定义一个变量 scope 并赋值 global scope; 2¡¢声明一个函数 checkscope ,在这个函数中 定义一个变量 scope 并赋值 local scope; 3¡¢在checkscope 函数中 又定义一个函数 f ,这个函数 只做了一件事£º返回scope 这个变量; 4¡¢最后返回并执行 f 这个函数; 5¡¢调用checkscope

              按照我们上面解释的javaScript中静态作用域理解£¬在执行 checkscope 这个函数的时候在函数内部执行的是f 这个函数£¬首先在 f 这个函数内部查找 scope 这个变量发现没有£¬继续在定义函数f的上面一层查找£¬发现在checkscope 这个函数作用域内 找到了scope的值 直接返回£¬至于 checkscope外面定义的scope没有理睬¡£

              让我们来分析一下上面例2的代码:

              1¡¢定义一个变量 scope 并赋值 global scope;

              2¡¢声明一个函数 checkscope 在这个函数中 定义一个变量 scope 并赋值 local scope;

              3¡¢在checkscope 函数中 又定义一个函数 f 这个函数 只做了一件事£º返回scope 这个变量;

              4¡¢最后单纯的返回 f 这个函数;

              5¡¢调用checkscope

              按照我们上面解释的javaScript中静态作用域理解£¬在执行 checkscope 这个函数的时候在函数内返回了函数f实际是在最外面调用的f但是由于javaScript是采用的词法作用域£¬因此函数的作用域基于函数创建的位置¡£

              而引用¡¶JavaScript权威?#25913;Ï¡?#30340;回答就是£º

              JavaScript 函数的执行用到了作用域链£¬这个作用域?#35789;?#22312;函数定义的时候创建的¡£嵌套的函数 f() 定义在这个作用域链里£¬其中的变量 scope 一定是局部变量£¬不管何时何地执行函数 f()£¬这种绑定在执行 f() 时依然?#34892;§¡?/p>

              点击复制链接 与好友分享!回本站首页
              相关TAG标签 js 词法作用域
              上一篇£º一文讲透前端开发所需网络知识
              下一篇£ºJavaScript常用工具方法封装
              相关文章
              图文推荐
              点击排行

              关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip?#38469;?#22521;训 | 举报?#34892;?/a>

              版权所有: 红黑联盟--致力于做实用的IT?#38469;?#23398;习网站

              ¼«ËÙ·ÉͧºÃ¼Ù
              <dl id="opymh"></dl>

              <div id="opymh"></div>
                  <div id="opymh"><tr id="opymh"></tr></div>

                    <em id="opymh"><ins id="opymh"><mark id="opymh"></mark></ins></em><sup id="opymh"><menu id="opymh"></menu></sup>

                    <em id="opymh"></em>

                    <em id="opymh"><ol id="opymh"></ol></em>

                          <dl id="opymh"></dl>

                          <div id="opymh"></div>
                              <div id="opymh"><tr id="opymh"></tr></div>

                                <em id="opymh"><ins id="opymh"><mark id="opymh"></mark></ins></em><sup id="opymh"><menu id="opymh"></menu></sup>

                                <em id="opymh"></em>

                                <em id="opymh"><ol id="opymh"></ol></em>