Patterns for avoiding name-space pollution - javascript

This article describes a number of patterns to avoid name-space pollution. I listed the patterns below with part of the sample code that was given in the article.
My question is: is there any commonly accepted 'best' way? What are the considerations when choosing one for my project?
Direct Assignment
var myApp = {}
myApp.id = 0;
myApp.next = function() {
return myApp.id++;
}
Using Object Literal Notation
var myApp = {
id: 0,
next: function() {
return this.id++;
}
}
The Module Pattern
var myApp = (function() {
var id= 0;
return {
next: function() {
return id++;
},
};
})();
Namespace Argument
var myApp = {};
(function(context) {
var id = 0;
context.next = function() {
return id++;
};
})(myApp);
this as a Namespace Proxy
var myApp = {};
(function() {
var id = 0;
this.next = function() {
return id++;
};
this.reset = function() {
id = 0;
}
}).apply(myApp);
The method I currently use
I used the following method in my own project. Is it bad?
function MyObj(){
this.someProperty = 'something';
}
MyObj.prototype.someFunction = function(){
this.someProperty =5;
}
myApp = new MyObj();

There is no commonly accepted best way. Sorry.
As Pointy said, your method involves creating the MyObj constructor function, which presumably will never be used again, as well as the myApp namespace object. It has at least one other minor disadvantage: you can't prevent yourself or someone else using the code from calling MyObj again, which is strange for something that's supposed to be your namespace.
Any of the IIFE-based solution should work fine, and they're mostly interchangeable. The module (or revealing module) is arguably the simplest. The namespace argument allows you to break a module over multiple files, something I choose never to do, but if that's what you want, it might be useful. I can't see any real advantages to the "this as a Namespace Proxy" method.

Related

How may I split my JavaScript classes across multiple files and yet have them belong to the same namespace?

I learnt that you could mimic namespaces in JavaScript by scoping your classes / objects inside a function expression or an object literal. That way the containing object or function provides a namespace and scope for the contained.
But for those to work, all the contained objects have to be within the same file, right?
Because if I had two namespace / naming container objects with the same name in two different files, they would overwrite each other depending on the order in which I included the source files.
File1.js
var Automtomobiles =
{
function Wheel() { ... }
};
File2.js
var Automtomobiles =
{
function Car() { ... }
};
How do I span objects / class definitions across multiple files but keep them within a same namespace?
Make Automtomobiles as global object
File1.js
var Automtomobiles = Automtomobiles || {};
Automtomobiles.wheel = function() {
}
File2.js
var Automtomobiles = Automtomobiles || {};
Automtomobiles.car = function() {
}
To make them global you can use window.Automtobiles = function() or to define an static property to a type. You can use .prototype
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
Person.prototype.nationality = "English";
console.log(new Person("john", "smith", 20, "red"));
Note how "English" is attached to each instance of Person after using the Prototype function
For your particular case, you can define Automtobiles then prototype it..
function Automtomobiles() {
};
Automtomobiles.prototype.wheel = function() { ... }
Automtomobiles.prototype.car = function() { ... }
Using pure javascript you could use the common notation that lot of libraries use. For one file:
var Automtomobiles;
(function (Automtomobiles) {
var Wheel = (function () {
function Wheel() {};
return Wheel;
}());
Automtomobiles.Wheel = Wheel;
})(Automtomobiles || (Automtomobiles = {}));
And the other file:
var Automtomobiles;
(function (Automtomobiles) {
var Car= (function () {
function Car() {};
return Car;
}());
Automtomobiles.Car= Car;
})(Automtomobiles || (Automtomobiles = {}));
Anyway, if you are open to use third party libraries, they could help you too. Long time ago I used Dojo declare feature, which manages the namespaces and class names for you, althoug I'm sure that at current exists more libraries to reach that.
In fact, you also could use Typescript, which is perfect to reach your goal and vey use to learn. The code generated by Typescript looks like the examples I posted above.

Private prototype methods that can share scope and access the instance

I'm looking for a pattern that both allows me to create a private scope that my function prototype has access to and I need to be able to access the instance from within that scope.
For example, this is how I am currently achieving "private methods" (disregard what the code actually does, just look at the structure.)
function InfoPreview() {
this.element = document.createElement('div');
}
//Private Methods
InfoPreview.prototype.__newLine = function () {
this.element.appendChild(createElement({tagName:'br'}));
};
InfoPreview.prototype.__padLeft = function(level) {
var padding = createElement({tagName: 'span'});
this.element.appendChild(padding);
$(padding).width(level * 10);
};
InfoPreview.prototype.__print = function(string) {
var span = createElement({ tagName: 'span', textContent: string });
this.element.appendChild(span);
this.element.style["margin-right"]='10px';
};
InfoPreview.prototype.__puts = function(string) {
this.__print(string);
this.__newLine();
};
//Public Methods
InfoPreview.prototype.update = function(info) {
$(this.element).empty();
for (var record in info) {
this.__puts(record);
}
};
Notice that I am not creating private methods at all, just utilizing a naming convention. Additionally notice that I have no way to cache chain-lookups, such as this.element.
I would like to create a private scope by utilizing a revealing module pattern, like this:
InfoPreview.prototype = (function() {
var self = this, //<- `this` is actually the global object now.
el = self.element;
var newLine = function () {
el.appendChild(createElement({tagName:'br'}));
};
var padLeft = function(level) {
var padding = createElement({tagName: 'span'});
el.appendChild(padding);
$(padding).width(level * 10);
};
var print = function(string) {
var span = createElement({ tagName: 'span', textContent: string });
el.appendChild(span);
el.style["margin-right"]='10px';
};
var puts = function(string) {
print(string);
newLine();
};
var update = function(info) {
$(el).empty();
for (var record in info) {
puts(record);
}
};
return {
update: update
};
})();
The above approach doesn't work however, because the value of this within the IIFE is the global object, not the instance. I need a way to access the instance.
Is there any downside of using a constructor pattern?
function Foo(constructorArg) {
/* private variables */
var privVar = 'I am private',
cArg = constructorArg;
/* public variables */
this.pubVar = 'I am public';
/* private function */
function privFunc() {
return 'I am a private function';
}
/* public function */
this.publicFunc = function() {
return 'I am a public function and I call privVar->"' + privVar + '" and privFunc->"' + privFunc() + '"';
}
}
var foo = new Foo('something');
console.log('foo.pubVar', foo.pubVar); //ok
console.log('foo.publicFunc()', foo.publicFunc()); // ok
console.log('foo.privVar', foo.privVar); // undefined
console.log('foo.privFunc', foo.privFunc()); //error
Why you should use it (as requested in comments):
Simply put, because it is the only (sane) way of creating a "true private scope", which was your question.
The alternative is using a convention which tell developers what properties and methods are private, usually by prefixing them with an underscore _, which you already implemented but disliked.
Note that constructor and prototype are different things and enable you to do different stuff. Nothing prevents you from mixing both up.
Memory usage
Regarding memory usage, in modern js engines, such as Google's V8 JavaScript Engine, the constructor pattern might actually be faster.
V8 has hidden types created internally for objects at runtime; objects with the same hidden class can then use the same optimized generated code.
For example:
function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(11, 22);
var p2 = new Point(33, 44);
// At this point, p1 and p2 have a shared hidden class
p2.z = 55;
// warning! p1 and p2 now have different hidden classes!
Prototype chaining always require two lookups, so it might even be a tiny inny LITTLE bit slower. Note: Can't back up on this, jsperf.com is down!
Constructor pattern is dirty (sic)
Performance was my reason. I hadn't realized that. However it still feels dirty to me
I don't know why you feel the constructor pattern is dirty. Maybe it's because it has some "specifics", limitations and potential pitfalls you should be aware
this can mean different things
It's easy to forget the new keyword causing weird and hard to debug bugs due to shared state
You can't easily split your object across multiple files (without resorting to a build tool or some 3rd party injector)
However, 1 and 2 are also true for prototype declaration style so...
if you feel this is not adequate, you might want to look at the module pattern.
Within each function, you will have access to the this value you want.
var Example = function() {};
Example.prototype = (function() {
var privateUpdate = function() {
document.getElementById('answer').innerHTML = this.foo;
}
return {
update: privateUpdate
}
})();
var e = new Example();
e.foo = 'bar';
e.update();
<div id="answer"></div>
As a variant on what Pointy is suggesting, you can try this pattern;
infoPreview.prototype = (function() {
var self = null;
var update = function(info) {
....
};
var firstUpdate = function(info) {
self = this;
functions.update = update;
update(info);
}
var functions = {
update: firstUpdate
};
return functions;
})();
Maybe something like that, without prototyping :
https://jsfiddle.net/ynwun1xb
var Fn = function(el) {
this.el = el;
var myMethod = function() {
console.log('do something in method with element', this.el);
}.bind(this);
return {
myPublicMethod: function() {
return myMethod();
}
}
}
var instancedFn = new Fn('first instance element')
.myPublicMethod()
;
var instancedFn2 = new Fn('second instance element')
.myPublicMethod()
;

JavaScript Class Best Practice?

I'm currently looking into different patterns for building classes in JavaScript. But no matther what pattern I see, there are still some things I am not really sure about.
var ItemManager = (function()
{
var p = function()
{
this.items= [];
};
p.prototype.addItem = function(item)
{
var self = this;
self.items.push(item);
};
return p;
}());
I create the simple class ItemManager, this class got the function addItem for adding any item to the collection. Now I don't really want the variable items, which represents the collection, to be public, this variable should be private, but I don't see any possible way to use a prototyped method to access private variables.
So what's the best practice in this case? Simply don't use private variables?
var ItemManager = function() {
var items = [];
return {
addItem : function(item) {
items.push(item);
},
removeItem : function() {
return items.pop();
}
}
};
var myItemManager = new ItemManager();
items variable becomes hidden after the execution of ItemManager function, but addItem and removeItem still share the access to items. See the Douglas Crockford's article on private variables in JavaScript for further investigation.
There are several ways to have private variables:
Closures, as in aga's example, which uses the Revealing Module Pattern. If you're using ES6 classes, you can hide private data in the constructor, though it looks pretty ugly to me.
[ES6] Symbols
[ES6] WeakMap
I favor Symbols, though they can still be found using reflection (i.e. not completely private). Example:
var Person = (function() {
var nameSymbol = Symbol('name');
​
function Person(name) {
this[nameSymbol] = name;
}
​
Person.prototype.getName = function() {
return this[nameSymbol];
};
​
return Person;
}());
So it's possible to have (reasonably) private variables, but unfortunately none of the solutions are as elegant as you'd like.
as GoldenerAal mentioned, they are not called classes, but functions
you have
var ItemManager = function (){
..
...
...
};
you could have:
function ItemManager(){
this.items = [];
function addItem(item){
...
};
};
you can then create an instance of ItemManager, only when you need to :
var itemManager = new ItemManager();
itemManager.addItem(<something here>);
http://javascript.crockford.com/private.html
variables inside a function only have the scope of that function, that variable is not a global variable (static variable).

What type of pattern does this JS adhere to?

I came across code similar to this recently,
// Simplified example..
var Application =
{
MemberVar1: null,
MemberVar2: null,
Initialize: function ()
{
Application.MemberVar1 = 'Foo';
Application.MemberVar2 = 'Bar';
console.log("Initializing..");
Application.GetMemberVars();
},
GetMemberVars: function ()
{
console.log(Application.MemberVar1 + ' ' + Application.MemberVar2);
}
};
$(Application.Initialize);
What is the name of this pattern/method/style? Utilizing OOP principles without using a style I've seen before, such as prototyping. What are the benefits of this style as opposed to other popular ones?
It's a simple one-off object literal that's being created... they can contain functions... perhaps that's what threw you.
The last line merely passes the Application.Initialize function to jQuery as a $(document).ready callback function
In light of the comments below, this is what the code actually does (and how you can write it a lot shorter/easier)
$(function()
{
console.log("Initializing..");
console.log("Foo Bar");//replace this with variables you declare #top of anon. function if you want
});
As a module (you can find out more about the module pattern here):
var Application = (function()
{
var memberVar1, memberVar2,
getMemberVars = function()
{
return memberVar1 + ' ' + memberVar2;
};
return {init: function()
{
memberVar1 = 'Foo';
memberVar2 = 'Bar';
console.log('initializing...');
console.log(getMemberVars());
}};
}());
$(Application.init);
Application is now an object literal, with only 1 property (init): a function that, because it was declared within the scope of that IIFE, has access to all variables local to that scope. That's the magic of closures for you. You can easily add getters and setters for the member vars, too:
var Application = (function()
{
var memberVars = {},//turned into object literal...
getMemberVars = function(all)
{
var i;
if(typeof all === 'string' || typeof all === 'number')
{
return memberVars[all];
}
all = [];
for (i in memberVars)
{
if (memberVars.hasOwnProperty(i))
{
all.push(memberVars[i]);
}
}
return all;//or all.join(' '), as you please
},
get = function(name)
{
return typeof name === 'undefined' ? name : memberVars[name];
},
set = function(name, val)
{
memberVars[name] = val;
};
return {init: function()
{
memberVars.one = 'Foo';
memberVars.two = 'Bar';
console.log('initializing...');
console.log(getMemberVars().join(' '));
},
get: get,
set: set};//just add getter and setter here
}());
This has the same behavior as your code:
var Application = (function() {
var app = {
MemberVar1: null,
MemberVar2: null,
GetMemberVars: function() { /* ... */},
Initialize: function() {
this.MemberVar1 = 'Foo';
this.MemberVar2 = 'Bar';
console.log('Initializing..');
this.getMemberVars();
}
};
$(function() {app.Initialize();});
return app;
}());
But there's a good chance that you don't really want that Initialize function hanging around. So this would simplify it:
var Application = (function() {
var app = {
MemberVar1: null,
MemberVar2: null,
GetMemberVars: function() { /* ... */}
};
$(function() {
app.MemberVar1 = 'Foo';
app.MemberVar2 = 'Bar';
console.log('Initializing..');
app.getMemberVars();
});
return app;
}());
And unless you're actually worried about code trying to access Application.MemberVar1, etc before jQuery's document.ready event, you can simplify it further to this:
var Application = (function() {
var app = {
GetMemberVars: function() { /* ... */}
};
$(function() {
app.MemberVar1 = 'Foo';
app.MemberVar2 = 'Bar';
console.log('Initializing..');
app.getMemberVars();
});
return app;
}());
I'm assuming that defining those MemberVars took some real work, and were not simple strings as in the example. If that's not the case, then I would switch this last to
var Application = (function() {
var app = {
MemberVar1: 'Foo';
MemberVar2: 'Bar';
GetMemberVars: function() { /* ... */}
};
$(function() {
console.log('Initializing..');
app.getMemberVars();
});
return app;
}());
You don't need to use prototype if you are going to use only one instance of some object.
In this case it's pretty clear the Application object is something unique and the author didn't intend there were going to be any additional copies of Application created.
Talking about style... that capital camel case looks ugly. The common agreement is to use CapitalCamelCase only for object constructors. I personally think it's ok to use for unique objects with logic too (Application). But using it for function names and variables should be avoided.
Talking about patterns... it's close to Singleton pattern. But don't think too much about it. All those OOP patterns from Java world lose part of their appeal in JS world. Some of them disintegrate completely. Concentrate on JS ways of solving problems.

Javascript Namespace - Is this a good pattern?

Objectives...
Remove vars, objects etc from the global object.
Remove possibility of collisions.
Firstly I implement the Yahoo namespace code (note for example purposes I am using ROOT as the root of my namespace)...
if (typeof ROOT == "undefined" || !ROOT) {
var ROOT = {};
}
ROOT.namespace = function () {
var a = arguments,
o = null,
i, j, d;
for (i = 0; i < a.length; i = i + 1) {
d = ("" + a[i]).split(".");
o = ROOT;
for (j = (d[0] == "ROOT") ? 1 : 0; j < d.length; j = j + 1) {
o[d[j]] = o[d[j]] || {};
o = o[d[j]];
}
}
return o;
}
Now I declare my 1st namespace...
ROOT.namespace("UI");
ROOT.UI = {
utc: 12345,
getUtc: function() {
return this.utc;
}
}
What I want to do here is to hold vars that I need for my UI (in this case the current time in UTC) so that they are not on the global object. I also want to provide some specific functionality. This should be available on every page without any sort of instanciation...
Now I want to have an object stored within my namespace structure. However, this object will need to be created multiple times. The objective here is to keep this inside my structure but allow it to be created as many times as I need. This is as follows:
ROOT.namespace("AirportFinder");
ROOT.AirportFinder = function(){
this.var1 = 99999;
this.Display = function() {
alert(this.var1);
}
}
And this is the sample code to instanciate the object...
var test1 = new ROOT.AirportFinder();
test1.Display();
Is this a good pattern?
It is indeed reasonable to have things defined on a namespace ROOT or something alike.
It's also better to use closures
(function() {
var AirportFinder = function() {
this.var1 = 99999;
this.Display = function() {
alert(this.var1);
}
};
// do Stuff with local AirportFinder here.
// If neccesary hoist to global namespace
ROOT.AirportFinder = AirportFinder;
}());
If they don't need to be global. I myself use an alias ($.foobar because jQuery is global anyway) for storing any global data.
I'm afraid I can't tell you waht the .namespace function does. It's not really neccessary.
My personal preference is to always use closures to create a private namespace and hoist anything to the global/shared namespace where neccesary. This reduces the global visibility/cluster to a minimum.
Slightly pointing you a little to the side, off the path of your question:
Have a look at YUI3 (http://developer.yahoo.com/yui/3/) - you don't have (to have) anything in the global namespace there, you get a private sandbox. Great concept, I love that library and its conocepts (YUI3, not talking about old YUI2). The way it does that is of course simple and you could do that too: The dynamic module loader of YUI3 loads your module (.js file(s)), creates a sandbox (just a closure) and calls your callback, giving it a handle for the sandbox. No other code anywhere can gain access to that sandbox and your own names. Within that sandbox you can (and should) go on using the various encapsulation patterns. This YUI3 concept is great for mashups with foreign code, especially when mashups become more dynamic in nature (e.g. user triggered), instead of just integrating Google Maps or other well-known APIs by the programmers themselves.
I tried to do a similar thing:
var namespace = function(str, root) {
var chunks = str.split('.');
if(!root)
root = window;
var current = root;
for(var i = 0; i < chunks.length; i++) {
if (!current.hasOwnProperty(chunks[i]))
current[chunks[i]] = {};
current = current[chunks[i]];
}
return current;
};
// ----- USAGE ------
namespace('ivar.util.array');
ivar.util.array.foo = 'bar';
alert(ivar.util.array.foo);
namespace('string', ivar.util);
ivar.util.string.foo = 'baz';
alert(ivar.util.string.foo);
Try it out: http://jsfiddle.net/stamat/Kb5xY/
Blog post: http://stamat.wordpress.com/2013/04/12/javascript-elegant-namespace-declaration/
By using an anonymous self-executing function, you can allow for public and private attributes/methods.
This is the pattern I like the most:
(function ($, MyObject, undefined) {
MyObject.publicFunction = function() {
console.log("This is a public function!");
};
var privateFunction = function() {
console.log("This is a private function!");
};
MyObject.sayStuff = function() {
this.publicFunction();
privateFunction();
privateNumber++;
console.log(privateNumber);
};
var privateNumber = 0;
// You can even nest the namespaces
MyObject.nestedNamespace = MyObject.nestedNamespace || {};
MyObject.nestedNamespace.logNestedMessage = function () {
console.log("Nested!!");
};
}(jQuery, window.MyObject = window.MyObject || {}));
MyObject.sayStuff();
MyObject.nestedNamespace.logNestedMessage();
MyObject.publicFunction();
Learned about it from the comments in this article.

Categories

Resources