javascript 模块依赖管理的本质深入详解

本文实例讲述了javascript 模块依赖管理的本质。分享给大家供大家参考,具体如下:

模块模式定义

模块是'javascript'的一种设计模式,它为函数定义一个包装函数,并且该包装函数的返回值与模块的API保持一致:

function createModule() {
 function hello(name) {
 console.log(name + '帅哥你好!');
 }

 return {
 hello: hello
 }
}
// 这里调用 createModule 来创建一个模块实例
var foo = createModule();
foo.hello('fayin');

单例模块模式

仔细研究上面的模块,我们发现每次调用 createModule 都会生成一个实例,很浪费。于是我们简单的包装一下,就有了单例模块模式:

var myModule = (function createModule() {
 function hello(name) {
 console.log(name + '帅哥你好!');
 }

 return {
 hello: hello
 }
})()

// 调用方式
myModule.hello('fayin')

模块依赖管理

现代大多数模块依赖管理器本质上都是将这种模块定义封装进一个友好的API。其核心的方法可以通过下面的例子一窥究竟:

// 通过模块的单例模式来保存定义的方法
var MyModules = (function() {

 var modules = {};

 function define(name, deps, impl) {
 console.log(deps.length)
 for(var i = 0, len = deps.length; i < len; i++) {
  // deps[i] 看做是函数名
  // modules[deps[i]] 是保存在 modules 对象上的一个属性为 deps[i] 的方法
  // 每次遍历将对应的方法绑定到函数名上
  deps[i] = modules[deps[i]]

 }
 // 在modules 对象上保存方法,其函数名为 name
 // 如函数 bar ,impl 为 bar 的函数体
 modules[name] = impl.apply(null, deps);

 console.log( modules)
 }

 function get(name) {
 return modules[name]
 }
 return {
 define: define,
 get: get
 };
})();

// 这里定义一个函数 bar,返回一个对象
MyModules.define('bar', [], function() {
 function hello(who) {
 return 'Let me introduce: ' + who;
 }
 return {
 hello: hello
 }
})

MyModules.define('foo', ['bar'], function(bar) {
 var hungry = 'hippo';

 function awesome() {
 return bar.hello(hungry).toUpperCase()
 }

 return {
 awesome: awesome
 }
})

var bar = MyModules.get('bar')
console.log(bar.hello('fay'))

var foo = MyModules.get('foo')

console.log(foo.awesome())

模块模式的缺陷

从上面的案例我们知道,这个模式是基于函数来实现的,它的优势这里不在赘述(参考jQuery),而它的缺点也非常的明显。由于函数的上下文环境是在运行时确定的,在编译期间无法确定它的依赖关系,在运行期间我们可以随意更改API,这导致基于函数的模块模式并不稳定。

而相比之下,ES6的模块API更加的稳定......

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

(0)

相关推荐

  • 关于Javascript模块化和命名空间管理的问题说明

    [关于模块化以及为什么要模块化] 先说说我们为什么要模块化吧.其实这还是和编码思想和代码管理的便利度相关(没有提及名字空间污染的问题是因为我相信已经考虑到模块化思想的编码者应该至少有了一套自己的命名法则,在中小型的站点中,名字空间污染的概率已经很小了,但也不代表不存在,后面会说这个问题). 其实模块化思想还是和面向对象的思想如出一辙,只不过可能我们口中所谓的"模块"是比所谓的"对象"更大的对象而已.我们把致力完成同一个目的的功能函数通过良好的封装组合起来,并且保证其

  • Javascript模块化编程(一)AMD规范(规范使用模块)

    这个系列的第一部分介绍了Javascript模块的基本写法,今天介绍如何规范地使用模块.  (接上文) 七.模块的规范 先想一想,为什么模块很重要? 因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块. 但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写法,岂不是乱了套!考虑到Javascript模块现在还没有官方规范,这一点就更重要了. 目前,通行的Javascript模块规范共有两种:CommonJS和AMD.我主要介绍AMD,

  • JavaScript模块管理的简单实现方式详解

    1. 为什么会有这个东西? 方便组织你的代码,提高项目的可维护性.一个项目的可维护性高不高,也体现一个程序员的水平,在如今越来越复杂的前端项目,这一点尤为重要. 2. 为什么不用requirejs,seajs等 它们功能强大,但是文件体积是个问题,此外还有就是业务有时候可能没那么复杂,正如开头所说的:keep it simple 3. 以下的实现从哪里来的? 这些借鉴了requirejs,seajs,commonjs等的实现,用于真实的项目,稳定运行,效果不错. 4. 适用场景 移动端页面,将j

  • 详解JavaScript模块化开发

    什么是模块化开发? 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应用也广泛起来了,jQuery,Ajax,Node.Js,MVC,MVVM等的助力也使得前端开发得到重视,也使得前端项目越来越复杂,然而,JavaScript却没有为组织代码提供任何明显帮助,甚至没有类的概念,更不用说模块(module)了,那么什么是模块呢? 一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.模块开发

  • Javascript模块化编程(三)require.js的用法及功能介绍

    这个系列的第一部分和第二部分,介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战. 我采用的是一个非常流行的库require.js.  一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载.下面的网页代码,相信很多人都见过. 复制代码 代码如下: <script src="1.js"></script> &l

  • Javascript模块化编程详解

    模块化编程是一种非常常见Javascript编程模式.它一般来说可以使得代码更易于理解,但是有许多优秀的实践还没有广为人知. 基础 我们首先简单地概述一下,自从三年前Eric Miraglia(YUI的开发者)第一次发表博客描述模块化模式以来的一些模块化模式.如果你已经对于这些模块化模式非常熟悉了,大可以直接跳过本节,从"进阶模式"开始阅读. 匿名闭包 这是一种让一切变为可能的基本结构,同时它也是Javascript最棒的特性.我们将简单地创建一个匿名函数并立即执行它.所有的代码将跑在

  • javascript模块化是什么及其优缺点介绍

    如今backbone.emberjs.spinejs.batmanjs 等MVC框架侵袭而来.CommonJS.AMD.NodeJS.RequireJS.SeaJS.curljs等模块化的JavaScript扑面而来.web前端已经演变成大前端,web前端的发展速度之快. 1)我们来看看什么是模块化? 模块化是一种将系统分离成独立功能部分的方法,可将系统分割成独立的功能部分,严格定义模块接口.模块间具有透明性.javascript中的模块在一些C.PHP.java中比较常见: c中使用inclu

  • Javascript模块模式分析

    Douglas Crockford已经传授了一个有用的单例模式(singleton pattern)实现此规则,我认为他的模式有益于你基于YUI的那些应用.Douglas叫它模块模式(module pattern).它是如下工作的: 创建一个命名空间对象:如果你使用YUI,可以用YAHOO.namespace()方法: YAHOO.namespace("myProject");这分配了一个空的myProject对象,是YAHOO的一个成员(如 果myProject已存在的话,则不会被覆

  • JavaScript模块化之使用requireJS按需加载

    模块加载器的概念可能稍微接触过前端开发的童鞋都不会陌生,通过模块加载器可以有效的解决这些问题: JS文件的依赖关系. 通过异步加载优化script标签引起的阻塞问题 可以简单的以文件为单位将功能模块化并实现复用 主流的JS模块加载器有requireJS,SeaJS等,加载器之间可能会因为遵循的规范不同有微妙的差别,从纯用户的角度出发,之所以选requireJS而不是SeaJS主要是因为: 功能实现上两者相差无几,没有明显的性能差异或重大问题. 文档丰富程度上,requireJS远远好于SeaJS

  • javascript 模块依赖管理的本质深入详解

    本文实例讲述了javascript 模块依赖管理的本质.分享给大家供大家参考,具体如下: 模块模式定义 模块是'javascript'的一种设计模式,它为函数定义一个包装函数,并且该包装函数的返回值与模块的API保持一致: function createModule() { function hello(name) { console.log(name + '帅哥你好!'); } return { hello: hello } } // 这里调用 createModule 来创建一个模块实例 v

  • 基于python中pygame模块的Linux下安装过程(详解)

    一.使用pip安装Python包 大多数较新的Python版本都自带pip,因此首先可检查系统是否已经安装了pip.在Python3中,pip有时被称为pip3. 1.在Linux和OS X系统中检查是否安装了pip 打开一个终端窗口,并执行如下命令: Python2.7中: zhuzhu@zhuzhu-K53SJ:~$ pip --version pip 8.1.1 from /usr/lib/python2.7/dist-packages (python 2.7) Python3.X中: z

  • typescript nodejs 依赖注入实现方法代码详解

    依赖注入通常也是我们所说的ioc模式,今天分享的是用typescript语言实现的ioc模式,这边用到的主要组件是 reflect-metadata 这个组件可以获取或者设置元数据信息,它的作用是拿到原数据后进行对象创建类似C#中的反射,先看第一段代码: import "reflect-metadata"; /** * 对象管理器 */ const _partialContainer = new Map<string, any>(); const PARAMTYPES =

  • JavaScript实现与web通信的方法详解

    web通信,一个特别大的topic,涉及面也是很广的.因最近学习了 javascript 中一些 web 通信知识,在这里总结下.文中应该会有理解错误或者表述不清晰的地方,还望斧正! 一.前言 1. comet技术 浏览器作为 Web 应用的前台,自身的处理功能比较有限.浏览器的发展需要客户端升级软件,同时由于客户端浏览器软件的多样性,在某种意义上,也影响了浏览器新技术的推广.在 Web 应用中,浏览器的主要工作是发送请求.解析服务器返回的信息以不同的风格显示.AJAX 是浏览器技术发展的成果,

  • go自动下载所有的依赖包go module使用详解

    今天在学习dubbo-go的时候,下载了dubbo-go的example,依赖的包太多了,之前都是手动下载某个依赖的包,现在手动一个一个 go get 那太麻烦了.因为我是搞java的,刚开始用go的时候感觉有点奇怪,go代码所依赖的所有的第三方库都放在GOPATH这个目录下面,这就导致了同一个库只能保存一个版本的代码.如果不同的项目依赖同一个第三方的库的不同版本,应该怎么解决?总不能改包名吧,看了一下 dubbo-samples/golang/的代码 发现了有个 go.mod文件,百度一下 g

  • 使用纯前端JavaScript实现Excel导入导出方法过程详解

    公司最近要为某国企做一个**统计和管理系统, 具体要求包含 Excel导入导出根据导入的数据进行展示报表图表展示(包括柱状图,折线图,饼图),而且还要求要有动画效果,扁平化风格Excel导出,并要提供客户端来管理Excel 文件... 要求真多! 现在总算是完成了,于是将我的经验分析出来. 在整个项目架构中,首先就要解决Excel导入的问题. 由于公司没有自己的框架做Excel IO,就只有通过其他渠道了. 嗯,我在github上找到了一个开源库xlsx,通过npm方式来安装. npm inst

  • Vue3中Vuex状态管理学习实战示例详解

    目录 引言 一.目录结构 二.版本依赖 三.配置Vuex 四.使用Vuex 引言 Vuex 是 Vue 全家桶重要组成之一,专为 Vue.js 应用程序开发的 状态管理模式 + 库 ,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 一.目录结构 demo/ package.json vite.config.js index.html public/ src/ api/ assets/ common/ components/ store/ index.

  • JavaScript中闭包的写法和作用详解

    1.什么是闭包 闭包是有权访问另一个函数作用域的变量的函数. 简单的说,Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内.而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数和声明的其他内部函数.当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包. 2.变量的作用域 要理解闭包,首先要理解变量的作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变

  • JavaScript注入漏洞的原理及防范(详解)

    初次接触: 初次接触JavaScript注入漏洞后,如果不对这种漏洞的作用机理仔细分析并提取出其发生的某种模式,你就不能做到快速的发现项目中可能存在的所有注入风险并在代码中防范. 发生模式: JavaScript注入漏洞能发生作用主要依赖两个关键的动作,一个是用户要能从界面中注入JavaScript到系统的内存或者后台存储系统中:二是系统中存在一些UI会展示用户注入的数据. 比如注入漏洞最常见的就是发生在各种类型的名字中,比如系统中的人名等等,因为名字往往会在各种系统上显示,如果在某个用户输入名

  • linecache模块加载和缓存文件内容详解

    linecache模块 接触到linecache这个模块是因为前两天读attrs源码的时候看到内部代码引用了这个模块来模拟一个假文件,带着一脸疑问顺便读了一下这个模块的源码,发现其实也就那么回事儿,代码不多,在这总结一下. linecache模块可以读取文件并将文件内容缓存起来,方便后面多次读取.这个模块原本被设计用来读取Python模块的源代码,所以当一个文件名不在指定路径下的时候,模块会通过搜索路径(search path)来尝试读取文件. 接口 linecache模块的__all__参数其

随机推荐