问题1:如何编写模块?

以下摘自《你不知道的JavaScript下卷》

在所有 JavaScript 代码中,唯一最重要的代码组织模式模块, 而且一直都是,我并不认为这是夸大其词。对于我本人,我认为也对于广泛社区来说,模块模式驱动了大多数代码。
3.3.1 旧方法
传统的模块模式基于一个带有内部变量和函数的外层函数,以及一个被返回的“publicAPI”,这个“public API”带有对内部数据和功能拥有闭包的方法。通常这样表达:
function Hello(name) {
     function greeting() {
         console.log( "Hello " + name + "!" );
     }
    // public API
   return {
       greeting: greeting
    };
}
var me = Hello( "Kyle" );
me.greeting(); // Hello Kyle!
继续调用 Hello(..) 模块可以产生多个实例。有时一个模块只作为单例(singleton,也就是说只需要一个实例),这种情况下前面的代码需要稍作修改,通常这样使用一个 IIFE:
var me = (function Hello(name){
        function greeting() {
      console.log( "Hello " + name + "!" );
}
// public API
return {
greeting: greeting
};
})( "Kyle" );
me.greeting(); // Hello Kyle!
这个模式是经过试验的。它也足够灵活,针对不同场景有多个变体。其中常用的是异步模块定义(Asynchronous Module Definition, AMD),还有一种是通用模块定义(Universal Module Definition, UMD)。这里我们不会具体介绍这些模式和技术,但网上有很多详尽的解释。

3.3.2 前进
对于 ES6 来说,我们不再需要依赖于封装函数和闭包提供模块支持。 ES6 中模块已经具备一等(first class)语法和功能支持。在讨论具体语法细节之前,有一点很重要,就是要理解 ES6 模块和过去我们处理模块的方式之间的显著概念区别。
• ES6 使用基于文件的模块,也就是说一个文件一个模块。目前,还没有把多个模块合并到单个文件中的标准方法。这意味着如果想要把 ES6 模块直接加载到浏览器 Web 应用中,需要分别加载,而不是作为一大组放在单个文件中加载。在过去,为了性能优化,后者这种加载方式是很常见的。期待 HTTP/2 的到来能够显著消除所有这样的性能担忧,因为它运行在持久 socket 连接上,所以能够高效并发、交替加载多个小文件。
• ES6模块的API是静态的。也就是说,需要在模块的公开API中静态定义所有最高层导出,之后无法补充。某些应用已经习惯了提供动态 API 定义的能力,可以根据对运行时情况的响应增加 / 删除 / 替换方法。这些用法或者改变自身以适应 ES6 静态 API,或者需要限制对二级对象属性 / 方法的动态修改。
• ES6 模块是单例。也就是说,模块只有一个实例,其中维护了它的状态。每次向其他模块导入这个模块的时候,得到的是对单个中心实例的引用。如果需要产生多个模块实例,那么你的模块需要提供某种工厂方法来实现这一点。
• 模块的公开 API 中暴露的属性和方法并不仅仅是普通的值或引用的赋值。它们是到内部模块定义中的标识符的实际绑定(几乎类似于指针)。在前 ES6 的模块中,如果把一个持有像数字或者字符串这样的原生值的属性放在公开
API 中,这个属性赋值是通过值复制赋值,任何对于对应变量的内部更新将会是独立的,不会影响 API 对象的公开复制。对于 ES6 来说,导出一个局部私有变量,即使当前它持有一个原生字符串 / 数字等,导出的都是到这个变量的绑定。如果模块修改了这个变量的值,外部导入绑定现在会决议到新的值。

• 导入模块和静态请求加载(如果还没加载的话)这个模块是一样的。如果是在浏览器环境中,这意味着通过网络阻塞加载;如果是在服务器上(比如 Node.js),则是从文件系统的阻塞加载。
但是,不要惊慌于这里的性能暗示。因为 ES6 模块具有静态定义,导入需求可以静态扫描预先加载,甚至是在使用这个模块之前。

关于如何处理这些加载请求, ES6 并没有实际指定或处理具体机制。这里有一个独立的模块加载器(Module Loader)的概念,其中每个宿主环境(浏览器、 Node.js 等)提供一个适合环境的默认加载器。导入模块时使用一个字符串值表示去哪里获得这个模块(URL、文件路径等),但是这个值对于你的程序来说是透明的,只对加载器本身有意义。
如果需要提供比默认加载器更细粒度的控制能力可以自定义加载器,默认加载器基本上没有粒度控制,因为它对于你的程序代码完全是不可见的。

你可以看到, ES6 模块将会为代码组织提供完整支持,包括封装、控制公开 API 以及引用依赖导入。但是实现方式非常特殊,可能可以也可能无法完全适应之前多年以来实现模块的方式。

CommonJS
还有一个类似、但并不完全兼容的模块语法 CommonJS, Node.js 生态系统下的开发者对此会很熟悉。不得不说,长远看来, ES6 模块从本质上说必然会取代之前所有的模块格式和标准,即使
是 CommonJS, 因为 ES6 模块是建立在语言的语法支持基础上的。最终它总会不可逆转地作为统治方法成为最后的赢家。但离那时还有很长的路要走。在服务器端 JavaScript 的世界里,已经有了成百上千的
CommonJS 风格模块,以及浏览器端十倍于此的各种格式标准的模块(UMD、 AMD、临时性的模块方案)。要迁移这些模块需要很多年才能初见成效。在此期间,模块 transpiler / 转换工具是必不可少的。你可能刚刚开始习惯这个新现实。不
管你是在编写普通模块、 AMD、 UMD、 CommonJS 还是 ES6,这些工具都不得不解析转化为对代码运行的所有环境都适用的形式。
对于 Node.js 来说,这可能意味着(目前的)目标是 CommonJS。对于浏览器来说,可能是 UMD 或者 AMD。接下来的几年里,随着这些工具的成熟和最佳实践的涌现,这一方面可能会变幻莫测。

由此,关于模块我的最好建议是:不管之前你虔诚地支持和熟悉哪种格式,现在开始开发
和理解 ES6 模块吧,因为它终将会使得其他模块方法消失。它是 JavaScript 模块的未来,
虽然现在有点落后。
3.3.3 新方法
支撑 ES6 模块的两个主要新关键字是 import export它们在语法上有许多微妙之处,所以我们来深入了解一下 。。。。。。

值得对照起来学习的模块化内容:

1、《JavaScript语言精髓和编程实践》第3章3.2节,从词法作用域的角度理解模块化的原理及好处。

2、《JavaScript权威指南第6版》第9章9.9节对如何实现模块做了简单但独到的解读。

3、《JavaScript编程精解》第二版中第10章模块部分,讲解了模块的实现方法以及常见的requier函数的原理,对了解commonjs模块有一定借鉴,虽然暂时没看懂,值得细细研究

转载于:https://www.cnblogs.com/menghome/p/9277760.html

JavaScript模块知识理解相关推荐

  1. 导出库的版本_了解 JavaScript 模块系统基础知识,搭建自己的库

    我想很多"前端工程师"都听过说过 "JavaScript 模块",那你们都知道如何处理它,以及它在日常工作中如何发挥作用吗? JS 模块系统到底是什么呢 随着 ...

  2. JavaScript基础知识与脚本语言总结

    1 Aptana插件安装 1.Aptana插件安装 <1>Aptana是一个非常强大,开源,JavaScript-focused的AJAX开发IDE. <2>它的特点包括: J ...

  3. JavaScript 进阶知识 - Ajax篇

    Ajax 前言 前面我们已经学习了js基础知识和一些简单的特效,基本上已经能够写出一个带有特效的静态页面了,为什么还要称之为静态页面呢?因为网页里的数据都是写死的,真正的工作中,我们是要通过Ajax技 ...

  4. JavaScript 进阶知识 - 高级篇

    JS高级 前言 经过前面几篇文章的学习,相信大家已经对js有了大部分的理解了,但是要想真正的掌握好js,本篇才是关键.由于js高级阶段的知识点比较难理解,所以本篇文章花了大量的时间去理思路,有可能有一 ...

  5. UWA学堂|测试模块知识Tree

    无论对于从业者还是正在读大学的技术萌新,学习的有效时间和个人时间都是有限的.高效学习者最在意的是时间的价值,一个需要体系化的知识地图就显得尤为重要. 本期为大家整理了UWA发布的与游戏测试开发相关的内 ...

  6. JavaScript高级知识汇总(高级篇)

    目录 JavaScript高级知识总结(高级篇) 一.深入基础 1.1数据类型 1.2数据变量与内存 1.3对象 1.4函数 回调函数 1.5 IIFE 1.6函数中的this 二.函数高级 2.1原 ...

  7. javascript模块_JavaScript模块第2部分:模块捆绑

    javascript模块 by Preethi Kasireddy 通过Preethi Kasireddy JavaScript模块第2部分:模块捆绑 (JavaScript Modules Part ...

  8. 判断字符串 正则_(重学前端 - JavaScript(模块一)) 14、引用类型之 RegExp (正则)(详述)...

    上一篇文章介绍了 JavaScript 中的 Date 类型,从地理方面的原理知识开始入手,如果大家认真看过上一篇文章,相信 JavaScript 中的 Date 类型已经难不住大家了!!! 但是今天 ...

  9. javascript模块_JavaScript中的模块

    javascript模块 JavaScript模块 (JavaScript Modules) One of the key features of programming fundamentals i ...

  10. 田永强:优秀的JavaScript模块是怎样炼成的

    转自:http://blog.jobbole.com/26101/ 引言:如今的JavaScript已经是Web上最流行的语言,没有之一.从GitHub上的语言排行榜https://github.co ...

最新文章

  1. COALESCE在SQL拼接中的大用途
  2. 用 Flask 来写个轻博客 (26) — 使用 Flask-Celery-Helper 实现异步任务
  3. 继承中类以及成员变量初始化的讨论。
  4. 2018第三届中国数字化零售创新国际峰会9月即将震撼来袭
  5. java foreach跳出本次循环_Java中提供三种常用的循环语句
  6. Java命令行界面(第15部分):Jargo
  7. 影响中国历史的十篇政治美文
  8. 图像识别:利用KNN实现手写数字识别(mnist数据集)
  9. webstorm 10.0.4 注册码
  10. python纵向制表符命令_Python中raw_input()中子命令的制表符完成
  11. hudi延迟日志命名
  12. Android设置按钮点击后变色(导航栏变色)
  13. zabbix利用sendEmail邮件报警
  14. HDU-1584蜘蛛牌
  15. 阿里云天池大赛——机器学习篇赛题解析(赛题一)上
  16. 记忆训练 0-100的110个数字对应编码
  17. mysql sphinx windows安装_window下安装sphinx实例
  18. 计算机主机的跳线怎么接,手把手教你台式机电脑主板跳线接法
  19. PowerDesigner Excel导入信息
  20. androidtv gms包_Android之GMS自我总结

热门文章

  1. relocation R_X86_64_PC32 against symbol ff_pw_9 can not be used when making a shared object
  2. UOS LINUX的开发测试,从来没有编译过什么应用?
  3. 主管已不安排代码工作,自己要明白问题所在
  4. 测试只描述现象,不下结论
  5. Ubuntu16.04+NVIDIA显卡驱动安装步骤
  6. DEBUG模式下,视频丢包严重;RELEASE就好了
  7. iOS启动画面不更新的问题
  8. android卡片式通知,原子通知+超级卡包,OriginOS比传统安卓更懂用户的需求
  9. 斜度符号标注_机械图纸尺寸标注规则
  10. android snackbar 底部,Android KitKat:Snackbar不在屏幕的底部