摘要:最后衍生出面向各种使用场景的模块标准。定义模块返回对象的匿名模块调用模块应用由模块组成,采用模块规范。其模块功能主要由两个命令构成和。命令用于规定模块的对外接口,导出模块暴露的命令用于输入其他模块提供的功能引入其他模块。
JS诞生之初面向简单页面开发, 没有模块的概念。后来页面逐渐复杂, 人类构造到 IIFE 立即执行函数来模拟 模块;之前也有雅虎的实践,使用命名空间 作为模块名。最后衍生出 面向各种使用场景 的 JS 模块标准。例如:
面向浏览器的 AMD
面向Nodejs的 CommonJS
对于这种分裂状态ES标准也在尽力弥合。 但是目前流行的实践是 UMD模式。
AMD 是requirejs 推广产出的规范,主要用于浏览器环境,通过define和require这两个定义模块、调用模块。
定义模块define("alpha", ["require", "exports", "beta"], function (require, exports, beta) { exports.verb = function() { return beta.verb(); //Or: return require("beta").verb(); } }); // 返回对象的匿名模块 define(["alpha"], function (alpha) { return { verb: function(){ return alpha.verb() + 2; } }; });调用模块
require(["foo", "bar"], function ( foo, bar ) { foo.doSomething(); }); define(function (require) { require(["a", "b"], function (a, b) { //modules a and b are now available for use. }); });2 commonJS
Node 应用由模块组成,采用 CommonJS 模块规范。
每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作。像Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS规范比较适用。但如果是浏览器环境,要从服务器加载模块,这是就必须采用异步模式。所以就有了 AMD CMD 解决方案。
// a.js // 相当于这里还有一行:var exports = module.exports;代码 exports.a = "Hello world"; // 相当于:module.exports.a = "Hello world"; // b.js var moduleA = require("./a.js"); console.log(moduleA.a); // 打印出hello world3 UMD
兼容 AMD 和 commonjs,也兼容 全局变量定义的 通用的模块化规范
(function (root, factory) { if (typeof define === "function" && define.amd) { // AMD define(["jquery"], factory); } else if (typeof exports === "object") { // Node, CommonJS-like module.exports = factory(require("jquery")); } else { // Browser globals (root is window) root.returnExports = factory(root.jQuery); } }(this, function ($) { function a(){}; // 私有方法,因为它没被返回 (见下面) function b(){}; // 公共方法,因为被返回了 function c(){}; // 公共方法,因为被返回了 // 暴露公共方法 return { b: b, c: c } }));4 ES6 Module
ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,旨在成为浏览器和服务器通用的模块解决方案。其模块功能主要由两个命令构成:export和import。
export命令用于规定模块的对外接口,导出模块暴露的api ;import命令用于输入其他模块提供的功能,引入其他模块。
/** 定义模块 math.js **/ var basicNum = 0; var add = function (a, b) { return a + b; }; export { basicNum, add }; /** 引用模块 **/ import { basicNum, add } from "./math"; function test(ele) { ele.textContent = add(99 + basicNum); }5 ES6 模块与 CommonJS 模块的差异
CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
ES6 模块的运行机制与 CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。换句话说,ES6 的import有点像 Unix 系统的“符号连接”,原始值变了,import加载的值也会跟着变。因此,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。
CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
运行时加载: CommonJS 模块就是对象;即在输入时是先加载整个模块,生成一个对象,然后再从这个对象上面读取方法,这种加载称为“运行时加载”。
编译时加载: ES6 模块不是对象,而是通过 export 命令显式指定输出的代码,import时采用静态命令的形式。即在import时可以指定加载某个输出值,而不是加载整个模块,这种加载称为“编译时加载”。
CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/104354.html
摘要:在中加密是一个很简单却又不能忽略的模块,数据只有加密起来才更安全,这样就散算据库密码泄漏也都是密文。当然也可以自定义构造方法,来制定用其他的方案进行加密。应用先示范下使用系统的来演示下简单的注入构造加密方案 在 Spring Security 中加密是一个很简单却又不能忽略的模块,数据只有加密起来才更安全,这样就散算据库密码泄漏也都是密文。本文分析对应的版本是 5.14。 概念 Spr...
阅读 2655·2021-11-24 10:44
阅读 1895·2021-11-22 13:53
阅读 1906·2021-09-30 09:47
阅读 3704·2021-09-22 16:00
阅读 2430·2021-09-08 09:36
阅读 2312·2019-08-30 15:53
阅读 2789·2019-08-30 15:48
阅读 976·2019-08-30 15:44