闭包之间怎么引用模块呢?
发布于 9 年前 作者 yakczh 4921 次浏览 最后一次编辑是 8 年前 来自 问答

第一个闭包中定义模块

(function( ){

var modA={a:100,b:200};
 
}).call(this);

第二个闭包要引用modA模块

(function(p){

var root=p;
 console.log(modA);

})(window);
9 回复

你把modA return 出来啊

@wandergis

	
	

(function( ){

var modA={a:100,b:200};
 return modA;
 
}).call(this);

 

(function(p){

var root=p;
 console.log(modA);

})(window);

ReferenceError: modA is not defined

console.log(modA);

	var modA = (function() {
	var modA = {
		a: 100,
		b: 200
	};
	return modA;

}).call(this);

(function(p, modA) {

	var root = p;
	console.log(modA);

})(window, modA);
var exports = {};
(function(exports) {
    exports.modA = function() {}
})(exports)
(function(exports) {
console.log(exports.modA);
})(exports)

@joesonw 这种有点象网易的写法

NTES =  {};
NTES.namespace = function() {
	var a = arguments,
		o = null,
		i, j, d, l;
	for (i = 0, l = a.length; i < l; i++) {
		d = ("" + a[i]).split(".");
		o = window.NTES;
		for (j = d[0] == "NTES" ? 1 : 0; j < d.length; j = j + 1) {
			o[d[j]] = o[d[j]] || {};
			o = o[d[j]]
		}
	}
	return o
};
(function($) {
	NTES.namespace("NTES.plugin");
	var util = NTES.util,
		extend = util.extend,
		plugin = NTES.plugin,
		addPlugin = function(name, pl) {
			plugin[name] = pl;
			return pl
		},
		getPlugin = function(name) {
			return plugin[name]
		};
	extend($, {
		addPlugin: addPlugin,
		getPlugin: getPlugin
	})
})(NTES);
(function($) {
	NTES.namespace("NTES.util.DOM");
	var util = NTES.util,
		extend = util.extend,
		insertAfter = function(a, b) {
			var c = b.parentNode;
			if (c.lastChild == b) {
				c.appendChild(a)
			} else {
				c.insertBefore(a, b.nextSibling)
			}
		},
		removeElement = function(a) {
			var b = a.parentNode;
			b && b.removeChild(a)
		},
		setCss = function(elm, options, unit) {
			unit = unit == undefined ? "px" : "";
			var name, style = elm.style;
			for (name in options) {
				if (options.hasOwnProperty(name)) {
					style[name] = options[name] + unit
				}
			}
			return elm
		},
		hide = function(elm) {
			return setCss(elm, {
				display: "none"
			}, "")
		},
		show = function(elm) {
			return setCss(elm, {
				display: ""
			}, "")
		};
	extend(util.DOM, {
		insertAfter: insertAfter,
		removeElement: removeElement,
		css: setCss,
		show: show,
		hide: hide
	})
})(NTES);

其中 NTES.namespace(“NTES.xxMod”); 这一句是用来做什么的, 只是声明一下吗?

这不是闭包(closure)吧?

@ruanyl 他的提问看起来好像没问题

@alsotang 恩,其实我只是觉得这个其实跟闭包关系不大,感觉更应该是如何组织代码的问题。一般我在没有用打包工具(例如webpack或者browserify)写前端代码的时候,如果需要分开不同的js文件组织项目,就会碰到这个问题。

一般我会简单这样写: moduleA.js

var App = (function(m) {
  m.func1 = function() {
  	// xxxx
  }
  return m;
})(App || {});

然后假如我有一个moduleB.js需要用到moduleA.js,那moduleB.js像这样

var App = (function(m) {
  m.func2 = function() {
  	//m.func1();
  }
  return m;
})(App || {});

然后判断添加一个判断环境的:

(function() {
 if (typeof module === 'object' && typeof module.exports === 'object') {
   module.exports = App;
 } else if (typeof define === 'function' && define.amd) {
   define(App);
 } else {
 	window.App = App;
 }
})();

最后简单粗暴的把文件concat起来就可以了。

两个闭包两条作用域链,只有部分环境对象共享(共用)。 如果变量是放在不共享的环境对象里,别的作用域链应该是无法访问到的。 只有把变量放在别的作用域能访问的环境对象里才能被别的作用域访问到。

回到顶部