JS学习之JavaScript模块化规范进化论

前言 JavaScript 语言诞生至今,模块规范化之路曲曲折折。

前言

JavaScript 语言诞生至今,模块规范化之路曲曲折折。社区先后出现了各种解决方案,包括 AMD、CMD、CommonJS 等,而后 ECMA 组织在 JavaScript 语言标准层面,增加了模块功能(因为该功能是在 ES2015 版本引入的,所以在下文中将之称为 ES6 module)。
今天我们就来聊聊,为什么会出现这些不同的模块规范,它们在所处的历史节点解决了哪些问题?

何谓模块化?

或根据功能、或根据数据、或根据业务,将一个大程序拆分成互相依赖的小文件,再用简单的方式拼装起来。

全局变量

演示项目

为了更好的理解各个模块规范,先增加一个简单的项目用于演示。

Window

在刀耕火种的前端原始社会,JS 文件之间的通信基本完全依靠window对象(借助 HTML、CSS 或后端等情况除外)。

  • config.js

    var api = 'https://github.com/ronffy';
    var config = {
      api: api,
    }
    
  • utils.js

    var utils = {
      request() {
        console.log(window.config.api);
      }
    }
    
  • main.js

    window.utils.request();
    
  • HTML

    <!-- index.html -->
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta >
        <title>【深度全面】JS模块规范进化论</title>
    </head>
    
    <body>
        <!-- 所有 script 标签必须保证顺序正确,否则会依赖报错 -->
        <script src="./js/config.js"></script>
        <script src="./js/utils.js"></script>
        <script src="./js/main.js"></script>
    </body>
    
    </html>
    
    

IIFE

浏览器环境下,在全局作用域声明的变量都是全局变量。全局变量存在命名冲突、占用内存无法被回收、代码可读性低等诸多问题。

这时,IIFE(匿名立即执行函数)出现了:

用 IIFE 重构 config.js:

(function (root) {
  var api = 'https://github.com/ronffy';
  var config = {
    api: api,
  };
  root.config = config;
}(window));

IIFE 的出现,使全局变量的声明数量得到了有效的控制。

命名空间

依靠window对象承载数据的方式是 “不可靠” 的,如window.config.api,如果window.config不存在,则window.config.api就会报错,所以为了避免这样的错误,代码里会大量的充斥var api = window.config && window.config.api;这样的代码。

这时,namespace登场了,简约版本的namespace函数的实现(只为演示,不要用于生产):

function namespace(tpl, value) {
    return tpl.split('.').reduce((pre, curr, i) => {
        return (pre[curr] = i === tpl.split('.').length - 1
            ? (value || pre[curr])
            : (pre[curr] || {}))
    }, window);
}

namespace设置window.app.a.b的值:

namespace('app.a.b', 3); // window.app.a.b 值为 3

namespace获取window.app.a.b的值:

var b = namespace('app.a.b');  // b 的值为 3
var d = namespace('app.a.c.d'); // d 的值为 undefined 

app.a.c值为undefined,但因为使用了namespace, 所以app.a.c.d不会报错,变量d的值为undefined

AMD

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值