I'm writting a library. Right now, I have everything written in a single .js file that goes like:
function doThis() {} var thisVar = 5;
I was not sure if that was right, so I considered:
function Lib() { this.doThis = function() {} this.thisVar = 5; } var lib = new Lib();
Then, on the main program files, I would have to call everything with "lib.", such as "lib.thisVar" or "lib.doThis();".
Any ideas on which would be better, or are they both acceptable? Thank you in advance.
The hierarchy consists of cabinets, drawers, folders, folder groups (this level is optional in usage), and within the folders are the documents; documents can only reside in the folders. Folder groups are an optional extra layer of division in the library structure.
The short answer is definitely YES ! but you need some intermediate steps ! Please note that ,you can write plain old JavaScript in a TypeScript project without any problems since JavaScript is a subset of TypeScript ,you only need these steps if you are planning to use an external JavaScript library with TypeScript .
To avoid cluttering the global namespace, I use a structure like this:
var MyLib = { vars: { var1: 'value1', var2: 'value2' }, func1: function () { return this.vars.var1; }, func2: function () { alert("This is func2"); } }; MyLib.func1(); MyLib.func2();
You will notice I placed all the variables into their own sub-object, this is done purely for easy reading and development.
EDIT 1:
Here is another method I use
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() );
This structure utilizes JS Closures and a constructor function, so its easy to keep private variables private.
EDIT 2:
In addition, I've also used a different closure setup that does not return a constructor (e.g. 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 : {}));
And to see it in action:
myLib('something').set('made public, outside of the closure by the `get` method'); myLib('something').get(function(a){ console.log(a); });
Please also take a look at the way I am exposing myLib
, taking into account where it's being run, and how it's being included.
EDIT 3 (7/2017):
As a full stack (w/Node.js) JavaScript engineer, and the advent of Browserify, I fully recommend the use of the Nodejs-style module
pattern utilizing either Gulp or Grunt as a build system for compiling a multi-file (decoupled, smaller bits of code) into one library.
This model helps encourage a more functional approach, allowing developers to abstract more common functions within a library into separate files, making development a lot easier.
Oh, and use ES6!
// file: src/divideIntByFour.js const divideIntByFour = (int) => { return int / 4; }; module.exports = divideIntByFour;
...As a siplified example
Look at the JavaScript Module pattern.
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
You could consider making your library compatible with require.js, which is a framework for doing exactly this kind of thing.
http://requirejs.org
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With