欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

模块浅析

程序员文章站 2022-07-12 12:09:13
...
/**
			 *模块浅析 
			 */
			function aa(){
				var name = 'Saber';
				var age = 20;
				function info(){
					console.log(name);
				}
				function another(){
					console.log(age);
				}
				return {
					info:info,
					another:another
				}
			}
			var bb = aa();
			bb.info();//Saber
			bb.another();//20
			/**
			 *这里来看一下上面的代码,
			 * 我们通过调用aa()函数来创建一个模块实例,如果不执行外部函数aa(),内部作用域和闭包都无法被创建
			 * aa()函数返回了一个对象,这个对象里有内部函数,却没有内部数据变量的引用,这里的内部变量保持了隐藏且私有的状态,
			 * 这里的这个对象可以看做模块的公共API
			 */
			/**
			 *说到这里,那么模块模式需要具备的两个必要条件是:
			 * 1、必须有外部函数,并且至少被调用一次(每次调用都会创建一个新的模块实例)
			 * 2、封闭函数必须至少返回一个内部函数,这样内部函数才能在私有作用域中形成闭包,然后对内部变量进行访问或者修改
			 */
			/**
			 * 上面的aa()函数可以被调用任意次数来创建新的模块实例,如果只需要一个实例的话,可以把这个aa函数改一下,变成一个单例模式
			 */
			var ss = (function(){
				var name = 'Dark';
				var age = 12;
				function info(){
					console.log(name);
				}
				function another(){
					console.log(age);
				}
				return {
					info:info,
					another:another
				}
			})();
			ss.info();//Dark
			ss.another();//12
			/**
			 *我们将模块函数改成了一个IIFE函数,立即执行这个函数之后将返回的对象直接赋给了ss变量,
			 * 当然,只要是函数就能够接收参数,这是没跑的了
			 */
			var dd = (function(str){
				var name = 'Dark';
				var age = 12;
				function info(){
					console.log(name);
				}
				function another(){
					console.log(age);
				}
				function special(){
					console.log(str);
				}
				return {
					info:info,
					another:another,
					special:special
				}
			})('传进一个参数!!!!');
			dd.special();//传进一个参数!!!!
			/**
			 *如果我们定义一个对象,这个对象返回的是公共的API,就像下面这样 
			 */
			function ff(){
				var str = '我就是一个普通的变量';
				function ww(){
					console.log(str);
				}
				function ee(){
					str = '普通变量被ee()函数改变了!!!!!'
				}
				var obj = {
					ww:ww,
					ee:ee
				}
				return obj;//这里和上面的唯一区别就是弄了一个对象,然后返回这个对象,并不是直接返回一个对象了
			}
			var hh = ff();
			hh.ww();//我就是一个普通的变量
			hh.ee();
			hh.ww();//普通变量被ee()函数改变了!!!!!
			/**
			 *我在书里看到这儿的时候,说是这样方便从内部对模块实例进行修改,但是从我自己来看的话,和直接返回没有啥区别啊,
			 * 这点我不太懂,如果有人看到这里,方便给解答一下就太好了!!!!
			 */
			/**
			 *现代模块机制 
			 */
			var rr = (function vv(){
				var modules = {};
				function define(name,deps,impl){
					for(var i = 0; i < deps.length; i++){
						deps[i] = modules[deps[i]];
					}
					modules[name] = impl.apply(impl,deps);//核心代码 :把impl返回的值赋值给了modules[name]上
				}
				function get(name){
					return modules[name];
				}
				return {
					define:define,
					get:get
				}
			})();
			rr.define('bar1',[],function(){
				function hello(who){
					return 'say hello to ' + who;
				}
				return {
					hello:hello
				}
			});//这个函数是将hello这个函数,放在了modules对象里,key叫做bar1
			rr.define('foo',['bar1'],function(foo){
				/**
				 * 第二个参数为bar1,作用是,在define函数里,for循环把modules里的bar1的值,赋给了bar1(deps[i]),
				 * 然后将bar1的值当做参数传进了impl中,所以这里的foo是能够接收到参数的,
				 * bar1的值为hello这个函数
				 */
				var hungry = 'hippo';
				function awesome(){
					console.log(bar.hello(hungry).toUpperCase())//SAY HELLO TO HIPPO
				}
				return {
					awesome:awesome
				}
			});//把awesome这个函数放进了modules里,key叫做foo
			var bar = rr.get('bar1');
			var foo = rr.get('foo');
			console.log(bar.hello('hippo'));//say hello to hippo
			foo.awesome();
			/**
			 *哇!上面这个代码好难懂啊,我整了半天才读懂他们,
			 * 但是我发现一件事,就是模块再怎么变,宗旨不会变
			 * 就是要有内部函数返回
			 * rr这个模块管理器的作用就是,接收函数,并把他们保存在一个根据名字来管理的模块列表中,就是modules里,进行存取
			 */
			/**
			 *未来的模块机制 
			 */
			/**
			 *bar.js 
			 */
			function hello(who){
				return 'say hello to ' + who;
			}
			export {hello}; 
			/**
			 *foo.js 
			 */
			import {hello} from './bar';//导入了hello这个模块
			var hungry = 'hippo';
			function awesome(){
				console.log(hello(hungry).toUpperCase());
			}
			export {awesome};
			/**
			 *baz.js 
			 */
			import {hello} from './foo';
			import {awesome} from './bar';
			console.log(hello('saber'));
			awesome();
			/**
			 * 这里用的是es6里的import和export,
			 * 说到这里,有几点需要注意的我说一下:
			 * 文件里可以有好多 export ,但是只能有一个 export default
			 * export 可以直接导出,类似:export let name1 = 'XXX',函数也可以直接导出,也可以有一个导出列表
			 * 类似:export { name1, name2};
			 * 但是用export导出的,导入的时候需要加上    { },类似:import {hello} from './foo';
			 * 但是export default,导入的时候不需要加,export default 用法和  export 一样的
			 * 可以直接导出变量函数,也可以弄一个导出列表
			 */
			/**
			 *es6中为模块增加了一级语法支持,将文件作为独立的模块来处理,
			 * 每个模块可以引入其他模块或API成员,可以导出自己的API
			 * 函数的模块不是能够稳定识别的模式,他们在运行时才会被考虑进来
			 * 而es6的模块更加稳定,在编译时就可以检查模块的引用是否真实存在,并且报错
			 * es6把独立文件作为模块进行引用,浏览器或引擎有一个模块加载起,可以导入模块时异步的加载模块文件
			 */
相关标签: 模块