Are there any dangers associated with using JavaScript namespaces? - javascript

Are there any dangers/caveats one should be aware of when creating JavaScript namespaces?
Our project is fairly expansive and we are running a lot of JavaScript files (20+, expecting more). It is impossible to have any code maintainability without using namespaces, so we are implementing them like so:
var namespace1 = {
doSomething: function() {
...
},
doSomethingElse: function() {
...
}
}
And then to create hierarchies, we link them like so:
var globalNamespace = {
functions1: namespace1,
functions2: namespace2,
...
}
This works fine, but it is essentially a "trick" to make JS behave as if it did have namespaces. Although this method gets used a lot, most literature on this seems to focus on how to do it, and not whether there are any possible drawbacks. As we write more JS code, this is quickly becoming an integral part of the way our system works. So it's important that it works seamlessly.
Were there any situations in which this "induced" namespace system caused you errors, or otherwise needed special attention? Can we safely expect identical behaviour across all browsers?

The way you define namespaces in your example it appears to create globals out of each namespace so you end up with
window.namespace1
window.namespace2
window.globalNamespace
window.globalNamespace.namespace1
window.globalNamespace.namespace2
So if you have anything that clobbers window.namespace1 it will also clobber window.globalNamespace.namespace1
edit:
Here's how we got around this problem:
namespacing = {
init: function(namespace) {
var spaces = [];
namespace.split('.').each(function(space) {
var curSpace = window,
i;
spaces.push(space);
for (i = 0; i < spaces.length; i++) {
if (typeof curSpace[spaces[i]] === 'undefined') {
curSpace[spaces[i]] = {};
}
curSpace = curSpace[spaces[i]];
}
});
}
};
Then you use it like this:
namespacing.init('globalNamespace.namespace1');
globalNamespace.namespace1.doSomething = function() { ... };
This way you don't have to introduce new global variables and you can confidently add to an existing namespace without clobbering other objects in it.

Since you are basically adding functions to objects and those objects into other objects, I would expect each browser to handle this the same way.
But if you want modularity, why not use a (relatively) simple framework like require.js? That will allow you and your team to write code in a modular fashion and allows the team to 'import' these modules where needed:
require(["helper/util"], function() {
//This function is called when scripts/helper/util.js is loaded.
});
Require.js will take care of dependencies, and it will also prevent polluting the global namespace.

We use a similar system at work and it does the job just fine. I don't see any drawbacks there could be; it's just objects and properties. For that same reason, cross browser compatibility should be good. You can end up having to write some long names to resolve to a particular function, like Foo.Bar.Test.Namespace2.Function, but even then that can be solved by assigning it to a variable before hand.

This is how I'd recommend doing it, so you stay out of the global scope entirely except for your "base" namespace. We do something similar where I work. Let's say you work for Acme co, and want ACME to be your base namespace.
At the top of every file, you'd include:
if (!window.ACME) { window.ACME = {} }
Then you just go and define whatever you want in terms of that.
ACME.Foo = {
bar: function () { console.log("baz"); }
}
If you want a deeper level of namespace, you just do the same thing for each level.
if (!window.ACME) { window.ACME = {} }
if (!ACME.Foo) { ACME.Foo = {} }
This way each file can be tested independently and they'll set up the namespace infrastructure automatically, but when you compile them together or if you test multiple files simultaneously, they won't keep overwriting things that are already defined.

Related

js - avoiding namespace conflict

Thus far I've worked only with relatively small projects (and mostly alone), but this time I have to collaborate with other programmers... basically because of that I must plan the structure of the website very carefully for the avoidance of spending hours debugging the code.
At this point I suppose doing that in the following manner. I divide my code in modules and store each module in a separate file inside an object (or a function) with a made-up name (lzheA, lzheB, lzheC etc.) to avoid conflicts whether an object with the same name was used in an another piece of code. When the document is loaded, I declare a variable (an object) that I use as a main namespace of the application. Properties of the object are the modules I defined before.
// file BI.lib.js
var lzheA = {
foo: function() {
},
bar: function() {
},
}
// file BI.init.js
function lzheK() {
BI.loadPage();
}
// file BI.loadPage.js
function lzheC() {
var result = document.getElementById('result');
result.innerHTML = "that worked";
}
// and so on
var lzheA,lzheB,lzheD,lzheE,lzheF,lzheG,lzheH,lzheI,lzheJ;
// doing the following when the document is loaded
var BI = {
lib: lzheA,
menu: lzheB,
loadPage: lzheC,
customScripts: lzheD,
_index: lzheE,
_briefs: lzheF,
_shop: lzheG,
_cases: lzheH,
_blog: lzheI,
_contacts: lzheJ,
init: lzheK,
}
BI.init();
https://jsfiddle.net/vwc2og57/2/
The question... is this way of structuring worth living or did I miss something because of lack of experience? Would the made-up names of the modules confuse you regardless of the fact that each one used only twice - while declaring the variable and assigning it to a property?
I consider the namespaces a good option when you want to modularize applications in Javascript. But I declare them in a different way
var myModule = myModule || {}; // This will allow to use the module in other places, declaring more than one specificComponent in other js file for example
myModule.specificComponent = (function(){
// Private things
var myVar = {};
var init = function() {
// Code
};
return {
init: init // Public Stuff
};
})();
If you want to call the init method, you would call it like this
myModule.specificComponent.init();
With this approach, i guarantee that the module will not be overwritten by another declaration in another place, and also I can declare internal components into my namespaces.
Also, the trick of just exposing what you want inside the return block, will make your component safer and you will be encapsulating your code in a pretty way.
Hope it helps

Calling one helper from another helper within the context of a template (Meteor 0.9.4)

As of Meteor 0.9.4, defining Template.MyTemplate.MyHelperFunction() is no longer valid.
We deprecated the Template.someTemplate.myHelper = ... syntax in favor of Template.someTemplate.helpers(...). Using the older syntax still works, but it prints a deprecation warning to the console.
This seemed fine to me, as it would (at the least) save some mis-typing and duplicated text. However, I soon discovered that the way I was building Meteor apps had leaned on an ability that this new version has deprecated. In my apps, I've been defining helpers/functions with the old syntax, then calling those methods from other helpers. I found it helped me keep my code clean and consistent.
For example, I might have a control like this:
//Common Method
Template.myTemplate.doCommonThing = function()
{
/* Commonly used method is defined here */
}
//Other Methods
Template.myTemplate.otherThing1 = function()
{
/* Do proprietary thing here */
Template.myTemplate.doCommonThing();
}
Template.myTemplate.otherThing2 = function()
{
/* Do proprietary thing here */
Template.myTemplate.doCommonThing();
}
But this does not appear to be available with the new method Meteor suggests (which makes me think I was wrong all along). My question is, What is the preferred way to share common, template-specific logic between a template's helpers?
Sorry if I'm being dull, but couldn't you declare the function as an object and assign it to multiple helpers? For instance:
// Common methods
doCommonThing = function(instance) // don't use *var* so that it becomes a global
{
/* Commonly used method is defined here */
}
Template.myTemplate.helpers({
otherThing1: function() {
var _instance = this; // assign original instance *this* to local variable for later use
/* Do proprietary thing here */
doCommonThing(_instance); // call the common function, while passing in the current template instance
},
otherThing2: function() {
var _instance = this;
/* Do some other proprietary thing here */
doCommonThing(_instance);
}
});
By the way, if you notice you're constantly duplicating the same helpers across multiple templates, it might help to use Template.registerHelper instead of assigning the same function to multiple places.

How to wrap loose variables and functions within a JavaScript object

I try to submit a simple Firefox add-on and got a message from AMO editor about wrapping of variables and functions within a JavaScript object in order to prevent conflicts with other add-ons that may be installed by users. The working code is very simple and looks:
function analyze() {
var uri = document.getElementById('urlbar').value;
var requrl="http://www.myanalyzingsiteaddress.com/" + (uri);
gBrowser.selectedTab = gBrowser.addTab(requrl);
}
Is it enough to make other var names to avoid eventual conflicts or could you point me to other code change, which would fulfill the AMO editor's instruction?
Thank you in advance!
Evgenij
You should have been pointed to Javascript Object Management from the XUL School tutorial.
analyze is a generic name. In an overlay there is only one scope/namespace which is shared by the browser code itself and any additional extension code. It is therefore possible that either the browser or another add-on uses analyze as well and boom.
You need to avoid that by making names a specifc as possible. E.g.
function my_addon_id_analyze() ...
Use an an object with a (pseudo) unique name.
if (!("org" in this)) {
this.org = {};
}
if (!("example" in org)) {
org.example = {};
}
org.example.addonid = {
analyze: function() ...
};
// call
org.example.addonid.analyze();
Or even "hide" your code in an anonymous function. This is then hidden from the DOM as well, so no more <button id="example.org.addonid.mybutton" onclick="analyze()"> event handling. But you can always use addEventListener.
(function() {
"use strict";
function analyze() ...
// wire up an event handler instead of onlick
document.getElementById("example.org.addonid.mybutton").addEventListener("click", analyze);
})();
Mix some/all of the above, as long as you avoid short/generic names:
if (!("org" in this)) {
this.org = {};
}
if (!("example" in org)) {
org.example = {};
}
org.example.addonid = (function() {
function analyze() ...
function notvisibleoutside() ...
// return object of "exported"/"visible" functions.
return {
analyze: analyze
};
})();
// call
org.example.addonid.analyze()
Also, keep in mind that missing var (or let/const) declarations will implicitly declare the variable in the global scope.
E.g.:
function abc() {
for (i = 0; i < 10; ++i) doSomething();
}
Will implicitly declare a variable named i in the global scope (in a XUL window the global scope is window, therefore this will create window.i). Implicit declarations may therefore not only cause conflicts but also create quasi memory leaks, e.g.
function call_me_to_leak_1MB() {
hugeArray = new ArrayBuffer(1<<20);
}
will declare window.hugeArray that lives as long as the browser window is open instead of using a local variable that gets garbage collected as soon as the variables goes out of scope (and there are no more other references, of course).
Using strict mode makes implicit declaration an error, which is helpful to catch and avoid such mistakes early.
So much for the Javascript part. There is still other stuff that might clash.
DOM Ids: Use unique <button id="example.org.addonid.mybutton">, or more CSS friendly <button id="example-org-addonid-mybutton"> (or at the very least something like addonid-mybutton) instead of <button id="mybutton">
CSS: Never style random elements.
No: button { color: green; }
Yep: #example-org-addonid-mybutton { color: green; }
chrome.manifest:
No: content generic content/
Yep: content example-org-addonid content/.

Sharing JS files across application

We're developing a mobile application and we're trying to figure out the best approach to share javascript functions across the application.
At the moment we have individual files that simply have:
var LIB = {
URL: "http://localhost/service",
connect: function() {
// connect to server
$.ajax({ url: this.URL }); // etc etc
// call a private function?
this._somethingElse();
},
_somethingElse: function() {
// do something else
}
};
Then we simply call things like:
LIB.connect(); or LIB.disconnect();
across any file.
This also gives us access to LIB.URL as well.
My question is whether this approach is the best?
I've seen people use the following approach as well, but to what benefit?
var LIB = function () {
this.URL = "http://localhost/service";
this.connect = function () {
var myself = this;
// connect to server
$.ajax({ url: this.URL }); // etc etc
// call a private function?
myself._somethingElse(); // best way to invoke a private function?
};
this._somethingElse = function () {
// do something else
};
};
This requires the following:
var lib = new LIB();
lib.connect();
EDIT:
I've also seen the following:
window.lib = (function () {
function Library () {
}
var lib = {
connect: function () {
// connect to server
}
};
return lib;
}());
I'm slightly confused with all these options.
It just depends on which you like better. I (on a personal level) prefer the former, but to each his own. The latter does have the disadvantage of requiring to either remember to declare the new before using it, or having to keep track of a already created one.
Additionally, on a technical level the first one should get slightly (as in, barely noticeable) performance, as you don't have to compute a new function.
Edit Yes, the first way is definitely the fastest.
I highly recommend going with a module system. Until ES6 comes along (http://wiki.ecmascript.org/doku.php?id=harmony:modules), you will have to use a 3rd party library in order to do this.
Each object/class/util/etc is a module.
A module exports a public api, whereas consuming modules import other modules by declaring their dependencies.
Two "standards" that exist: AMD and CommonJS. In the browser, a library like RequireJS, which uses the AMD standard, is very popular. I recommend checking out their site first: http://requirejs.org/ and see their examples.
The main advantage here is that you only expose the public api, which allows you to create a sandbox of your functionality. It's also more explicit as it's really easy to see what your module depends on, instead of relying on global objects.
There are several different approaches to structuring JavaScript code for re-usability. You can research these and decide which is best. Me personally, I have used the second approach that you've outlined. However, I separate my code into sections and actually adhere to an MVVM structure. So for instance, I have a name space called models and view models. Each of my js files begins with:
window.[APP NAME].Models.[CLASS/MODULE NAME] or window.[APP NAME].Models.[CLASS/MODULE NAME]
So, let's say I have a namespace called mynamespace and I have a module/class called myclass. My js file would begin with:
window.MYNAMESPACE = window.MYNAMESPACE || {};
window.MYNAMESPACE.ViewModels = window.MYNAMESPACE.ViewModels || {};
window.MYNAMESPACE.ViewModels.MyClass = function () {
// a public function
this.func1 = function () {
};
// a private function
function func2() {
}
};
I would then consume that class by calling:
var myClassModel = new window.MYNAMESPACE.ViewModels.MyClass();
myClassModel.func1();
This gives you some nice encapsulation of your code. Some of the other patterns you can research/google are: Prototype Pattern, Module Pattern, Revealing Module Pattern, and the Revealing Prototype Pattern.
I hope that helps but if you have any questions on what I've just said, feel free to comment on this post.

understanding a modular javascript pattern

I'm trying to write 'better' javascript.
Below is one pattern I've found, and am trying to adopt. However, I'm slightly confused about its use.
Say, for example, I've got a page called "Jobs". Any JS functionality on that page would be encapsulated in something like:
window.jobs = (function(jobs, $, undefined){
return {
addNew: function(){
// job-adding code
}
}
})(window.jobs|| {}, jQuery);
$(function(){
$('.add_job').on('click', function(event){
event.preventDefault();
window.jobs.addNew();
});
});
As you can probably deduct, all I've done is replaced all the code that would have sat inside the anonymous event-handler function, with a call to a function in my global jobs object. I'm not sure why that's a good thing, other than it's reduced the possibility of variable collisions and made the whole thing a bit neater, but that's good enough for me.
The - probably fairly obvious - question is: all my event-binding init-type stuff is still sitting outside my shiny new jobs object: where should it be? Inside the jobs object? Inside the return object inside the jobs object? Inside an init() function?
I'm just trying to get a sense of a stable, basic framework for putting simple functionality in. I'm not building JS apps, I'd just like to write code that's a little more robust and maintainable than it is currently. Any and all suggestions are warmly welcomed :)
You can break down your application in whatever number of modules / objects you like too.
For instance, you can have another object / module which caches and defines all your DOM nodes and another one, which just handles any event. So for instance:
(function ( win, doc, $, undef ) {
win.myApp = win.myApp || { };
var eventHandler = {
onJobClick: function( event ) {
event.preventDefault();
myApp.addNew();
}
};
var nodes = (function() {
var rootNode = $( '.myRootNode' ),
addJob = rootNode.find( '.add_job' );
return {
rootNode: rootNode,
addJob: addJob
};
}());
$(function() {
myApp.nodes.addJob.on( 'click', myApp.handler.onJobClick );
});
myApp.nodes = nodes;
myApp.handler = eventHandler;
}( this, this.document, jQuery ));
It doesn't really matter how you create singletons in this (module) pattern, either as literal, constructor, Object.create() or whatnot. It needs to fit your requirements.
But you should try to create as many specific modules/objects as necesarry. Of course, if makes even more sense to separate those singletons / modules / objects into multiple javascript files and load them on demand and before you can say knife, you're in the world of modular programming patterns, dealing with requireJS and AMD or CommonJS modules.
Encapsulation-wise, you're fine: you could even just declare addNew in the jQuery closure and you'd still avoid the global scope. I think what you're getting at is more of implementing something close to an MVC architecture.
Something I like to do is create an object that you instantiate with a DOM element and that takes care of its own bindings/provides methods to access its controls etc.
Example:
// (pretend we're inside a closure already)
var myObj = function(args){
this.el = args.el; // just a selector, e.g. #myId
this.html = args.html;
this.bindings = args.bindings || {};
}
myObj.prototype.appendTo = function(elem){
elem.innerHTML += this.html;
this.bindControls();
};
myObj.prototype.remove = function(){
$(this.el).remove(); // using jQuery
};
myObj.prototype.bindControls = function(){
for(var i in this.bindings){ // event#selector : function
var boundFunc = function(e){ return this.bindings[i].call(this,e); };
$(this.el).on(i,boundFunc);
}
};
The way you are doing it right now is exactly how I do it also, I typically create the window objects inside the anonymous function itself and then declare inside that (in this case: jClass = window.jClass).
(function (jClass, $, undefined) {
/// <param name="$" type="jQuery" />
var VERSION = '1.31';
UPDATED_DATE = '7/20/2012';
// Private Namespace Variables
var _self = jClass; // internal self-reference
jClass = window.jClass; // (fix for intellisense)
$ = jQuery; // save rights to jQuery (also fixes vsdoc Intellisense)
// I init my namespace from inside itself
$(function () {
jClass.init('branchName');
});
jClass.init = function(branch) {
this._branch = branch;
this._globalFunctionality({ globalDatePicker: true });
this._jQueryValidateAdditions();
//put GLOBAL IMAGES to preload in the array
this._preloadImages( [''] );
this._log('*******************************************************');
this._log('jClass Loaded Successfully :: v' + VERSION + ' :: Last Updated: ' + UPDATED_DATE);
this._log('*******************************************************\n');
};
jClass._log = function() {
//NOTE: Global Log (cross browser Console.log - for Testing purposes)
//ENDNOTE
try { console.log.apply(console, arguments); }
catch (e) {
try { opera.postError.apply(opera, arguments); }
catch (e) { /* IE Currently shut OFF : alert(Array.prototype.join.call(arguments, ' '));*/ }
}
};
}(window.jClass= window.jClass|| {}, jQuery));
The reason I leave them completely anonymous like this, is that let's say in another file I want to add much more functionality to this jClass. I simply create another:
(function jClass, $, undefined) {
jClass.newFunction = function (params) {
// new stuff here
};
}(window.jClass = window.jClass || {}, jQuery))
As you can see I prefer the object.object notation, but you can use object literals object : object, it's up to you!
Either way by leaving all of this separate, and encapsulated without actual page logic makes it easier to have this within a globalJS file and every page on your site able to use it. Such as the example below.
jClass._log('log this text for me');
You don't want to intertwine model logic with your business logic, so your on the right path separating the two, and allowing for your global namespace/class/etc to be more flexible!
You can find here a comprehensive study on module pattern here: http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html It covers all the aspects of block-scoped module approach. However in practice you gonna have quite a number files encapsulating you code, so the question is how to combine them property. AMD... multiple HTTP requests produced by every module loading will rather harm your page response time. So you can go with CommonJS compiled to a single JavaScript file suitable for in-browser use. Take a look how easy it is http://dsheiko.github.io/cjsc/

Categories