最新公告
  • 欢迎您访问爱上源码网,分享精品整站源码,网站模板,游戏源码,APP小程序源码以及视频教程免费下载;服务永无止境!立即加入我们
  • JavaScript作用域的全面解析(附代码)

    本篇文章给大家带来的内容是关于JavaScript作用域的全面解析(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

    作用域决定了变量的生命周期和可见性,变量在作用域范围之外是不可见的。

    JavaScript 的作用域包括:模块作用域,函数作用域,块作用域,词法作用域和全局作用域。

    全局作用域

    在任何函数、块或模块范围之外定义的变量具有全局作用域。可以在程序的任意位置访问全局变量。

    当启用模块系统时,创建全局变量会变得困难,但仍然可以做到这一点。可以在 HTML 中定义一个变量,这个变量需要在函数之外声明,这样就可以创建一个全局变量:

    <script>
      let GLOBAL_DATA = { value : 1};
    </script>
    console.log(GLOBAL_DATA);

    当没有模块系统时,创建全局变量会容易很多。在任何文件中的函数外声明的变量都是全局变量。

    全局变量贯穿于程序的整个生命周期。

    另一种创建全局变量的方法是在程序的任意位置使用 window 全局对象:

    window.GLOBAL_DATA = { value: 1 };

    这样 GLOBAL_DATA 变量会随处可见。

    console.log(GLOBAL_DATA)

    不过你也知道这种做法是不好的。

    模块作用域

    如果不启用模块,在所有函数之外声明的变量是全局变量。在模块中,在函数外部声明的变量都是隐藏的,除非显式导出,否则不可用于其他模块。

    导出使函数或对象可用于其他模块。在这个例子中,我从模块文件 sequence.js 中导出了一个函数:

    // in sequence.js
    export { sequence, toList, take };

    当前模块可以通过导入来使用其他模块的函数或对象成。

    import { sequence, toList, toList } from "./sequence";

    在某种程度上,我们可以认为模块是一个自动执行的函数,它将 import 的数据作为输入,然后返回 export 的数据。

    函数作用域

    函数作用域意味着在函数中定义的参数和变量在函数内的任何位置都可见,但是在函数外部不可见。

    下面是一个自动执行的函数,被称为IIFE。

    (function autoexecute() {
        let x = 1;
    })();
    console.log(x);
    //Uncaught ReferenceError: x is not defined

    IIFE 的意思是立即调用函数表达式,是一个在定义后立即运行的函数。

    var 声明的变量只有函数作用域。更重要的是,用 var 声明的变量被提升到其作用域的顶部。通过这种方式,可以在声明之前访问它们。看看下面的代码:

    function doSomething(){
      console.log(x);
      var x = 1;
    }
    doSomething(); //undefined

    这种事不会发生在 let 中。用 let 声明的变量只能在定义后访问。

    function doSomething(){
      console.log(x);
      let x = 1;
    }
    doSomething();
    //Uncaught ReferenceError: x is not defined

    var 声明的变量可以在同一作用域下多次重新声明:

    function doSomething(){
      var x = 1
      var x = 2;
      console.log(x);
    }
    doSomething();

    letconst 声明的变量不能在同一作用域内重新声明:

    function doSomething(){
      let x = 1
      let x = 2;
    }
    //Uncaught SyntaxError: Identifier 'x' has already been declared

    也许我们可以不必关心这一点,因为 var 已经开始变得过时了。

    块作用域

    块作用域用花括号定义。它由 {} 分隔。

    letconst 声明的变量可以受到块作用域的约束,只能在定义它们的块中访问。

    思考下面这段关于 let 块范围的代码:

    let x = 1;
    { 
      let x = 2;
    }
    console.log(x); //1

    相反,var 声明不受块作用域的约束:

    var x = 1;
    { 
      var x = 2;
    }
    console.log(x); //2

    另一个常见问题是在循环中使用类似 setTimeout() 的异步操作。下面的循环代码将显示五次数字 5。

    (function run(){
        for(var i=0; i<5; i++){
            setTimeout(function logValue(){
                console.log(i);         //5
            }, 100);
        }
    })();

    带有 let 声明的 for 循环语句在每次循环都会创建一个新的变量并设置到块作用域。下一段循环代码将会显示 0 1 2 3 4 5

    (function run(){
      for(let i=0; i<5; i++){
        setTimeout(function log(){
          console.log(i); //0 1 2 3 4
        }, 100);
      }
    })();

    词法作用域

    词法作用域是内部函数访问定义它的外部作用域的能力。

    看一下这段代码:

    (function autorun(){
        let x = 1;
        function log(){
          console.log(x);
        };
        
        function run(fn){
          let x = 100;
          fn();
        }
        
        run(log);//1
    })();

    log 函数是一个闭包。它从父函数 autorun() 引用 x 变量,而不是 run() 函数中的 x 变量。

    闭包函数可以访问创建它的作用域,而不是它自己的作用域。

    autorun() 的局部函数作用域是 log() 函数的词法作用域。

    作用域链

    每个作用域都有一个指向父作用域的链接。当使用变量时,JavaScript 会向下查看作用域链,直到它找到所请求的变量或者到达全局作用域(即作用域链的末尾)。
    看下面这个例子:

    let x0 = 0;
    (function autorun1(){
     let x1 = 1;
      
     (function autorun2(){
       let x2 = 2;
      
       (function autorun3(){
         let x3 = 3;
          
         console.log(x0 + " " + x1 + " " + x2 + " " + x3);//0 1 2 3
        })();
      })();
    })();

    内部函数 autorun3() 可以访问本地 x3 变量。还可以从外部函数访问变量 x1x2 和全局变量 x0

    如果找不到变量,它将在严格模式下返回错误。

    "use strict";
    x = 1;
    console.log(x)
    //Uncaught ReferenceError: x is not defined

    非严格模式也被称为“草率模式”,它会草率的创建一个全局变量。

    x = 1;
    console.log(x); //1

    总结

    在全局作用域中定义的变量可在程序的任何位置使用。

    在模块中,在函数外部声明的变量都是隐藏的,除非被显式导出,否则不可用于其他模块。

    函数作用域意味着函数中定义的参数和变量在函数的任意位置都可见

    letconst 声明的变量具有块作用域。 var 没有块作用域。

    【相关推荐:JavaScript视频教程】

    以上就是JavaScript作用域的全面解析(附代码)的详细内容,更多请关注爱上源码网其它相关文章!

  • 微信
  • 分享
  • 相关标签:作用域 javascript 前端
  • 本文转载于:segmentfault,如有侵犯,请联系916990011@qq.com删除
    • 上一篇:使用RxJS管理React应用状态的介绍
    • 下一篇:基于 jQuery的键盘事件监听控件的介绍(代码示例)

    相关文章

    相关视频

    • JavaScript如何检查一个对象是否为空(代码…
    • Javascript混淆与解混淆的详细介绍(附代码…
    • javascript现继承的四种方式(代码示例)
    • javascript实现小型区块链的方法介绍(附代…
    • JavaScript作用域的全面解析(附代码)
    • JavaScript中对象的常见用法(上)
    • JavaScript中对象的常见用法(下)
    • JavaScript Math 对象

    本文有爱上源码下载完入驻作者发布,如果对您版权造成侵害,可以联系本站站长管理进行维权删除,本站收到维权24小时内进行处理,谢谢您关注23ym.cn!
    本站分享大量程序员技术文章以及对编程开发的初级入门教程,包括图文讲解笔记和高清视频下载~

    重要声明:
    1.本站视频教程,软件及网站源码版权均属于原作者所有,您必须在下载后的24个小时之内,从您的电脑中删除!非法商业用途,后果自负!
    2.本站不保证所提供下载资源的安全性和完整性,仅供下载学习之用!如链接失效或资源含外站广告,请联系客服处理!给予奖励!
    3.本站所有资源来源于用户上传和网络,因此不包含技术服务请大家谅解!本站提供有偿服务!如有侵权请联系在线客服!
    4.如您手中有优质资源或教程,可以自助投稿发布,成功分享后有奖励和额外收入!
    5.如您需要正版微擎模块可联系本站客服,我们有价值30w+商业微擎应用出售微擎坑位和招收代理!
    6.400电话/软著/ICP,EDI许可证/商标特价办理中!
    爱上源码下载网 » JavaScript作用域的全面解析(附代码)

    常见问题FAQ

    从网站下载的源码都有安装教程么?不会安装怎么办?
    本站发布的网站源码和模板资源大部分在压缩包内都有教程,如您不会安装可以联系本站在线技术进行付费安装。
    爱上源码的所有源码都是亲测能正常运行的么?
    本站目前拥有资源10w+,包含整站源码,网站模板,游戏源码,小程序源码,视频教程,破解软件等,每天也在测试更新;因时间和精力有限我们无法对资源进行一一测试,只能保证所分享资源内容无误,希望理解。
    我手中的优质资源可以在你这换钱或者VIP么?
    爱上源码支持投稿,欢迎发布您手中的优质资源进行售卖;本站VIP支持免费获取,目前邀请10人注册爱上源码即可免费获取VIP。
    爱上源码除了资源分享还有其他业务没?
    【价值30W+微擎模块出售正版商业微擎坑位及招收代理,详情咨询本站客服!】我们团队目前运营并推广几套商业化saas智能小程序系统能满足大部分小程序开发需求,并由SaaS和独立部署版商城小程序系统;另外销售400电话,各种ICP/EDI资质证书办理,软著和商标注册服务等。

    发表评论

    • 32会员总数(位)
    • 35644资源总数(个)
    • 0本周发布(个)
    • 0 今日发布(个)
    • 666稳定运行(天)

    提供最优质的资源集合

    开通VIP 源码下载