为了避免混淆全局命名空间,我使用了这样的结构:
var MyLib = {
vars: {
var1: 'value1',
var2: 'value2'
},
func1: function () {
return this.vars.var1;
},
func2: function () {
alert("This is func2");
}
};
MyLib.func1();
MyLib.func2();
您会注意到我将所有变量都放入了它们自己的子对象中,这样做纯粹是为了便于阅读和开发。
编辑1:
这是我使用的另一种方法
var MyLib = (function MyLib() {
var _privateVars = {
"someVar": "This value made public by `someMethod`",
"privateVar": "Can't see this value"
};
// Return the constructor
return function MyLibConstructor() {
var _this = this; // Cache the `this` keyword
_this.someMethod = function () {
// Access a private variable
return _privateVars.someVar;
};
_this.someOtherMethod = function () {
// Some other functionality
};
};
}());
var myLib = new MyLib(); // invoke
console.log( myLib.someMethod() );
该结构利用JS 闭包和构造函数,因此很容易将私有变量保持私有。
编辑2:
此外,我还使用了不返回构造函数的不同闭包设置(例如var x = new MyLib();
)。
(function(window) {
var _private = {},
methods = {},
topic, init;
methods.set = function(value) {
// Set the property & value
_private[topic] = value;
return this;
};
// A simple get method
methods.get = function(callback) {
var response = null;
// Return the value of topic (property) in a callback
if (!!callback && typeof callback === 'function') {
if (_private.hasOwnProperty(topic)) {
response = _private[topic];
}
callback.call(this, response);
}
return this;
};
// Init method setting the topic and returning the methods.
init = function(_topic) {
topic = _topic;
return methods;
};
// Exposure when being used in an AMD environment, e.g. RequireJS
if (typeof define === 'function' && define.amd) {
define(function() {
return init;
});
return;
}
// Exposure when being used with NodeJS
if ('undefined' !== typeof module && module.exports) {
module.exports = init;
return;
}
// Last-in-the-line exposure to the window, if it exists
window.myLib = init;
// This line either passes the `window` as an argument or
// an empty Object-literal if `window` is not defined.
}(('undefined' !== typeof window) ? window : {}));
并在行动中看到它:
myLib('something').set('made public, outside of the closure by the `get` method');
myLib('something').get(function(a){
console.log(a);
});
还请看一下我公开的方式myLib
,考虑到它在哪里运行,以及它是如何被包含在内的。
编辑 3 (7/2017):
作为一个全栈(w/Node.js)JavaScript 工程师,随着 Browserify 的出现,我完全推荐使用 Nodejs 风格的module
模式,利用 Gulp 或 Grunt 作为构建系统来编译多文件(解耦,更小代码位)到一个库中。
该模型有助于鼓励采用更实用的方法,允许开发人员将库中更常见的功能抽象到单独的文件中,从而使开发变得更加容易。
哦,使用 ES6!
// file: src/divideIntByFour.js
const divideIntByFour = (int) => {
return int / 4;
};
module.exports = divideIntByFour;
...作为一个简单的例子