6

I'm working on an application in the browser and I would like to make sure that my code does not conflict with code from other libraries or with possible calls added by browser manufacturers in the future.

In my environment I would avoid collisions by using a unique application name and placing all my classes and code in my domain like so:

package {
    import com.mydomain.controls.*; // my domain

    public class MyApplication {
        var button:Button = new com.mydomain.Button();
        button.text = "Hello World";
        addChild(button);
    }

}

Or when I'm using a declarative language I would define my namespace URI and prefix like so:

<s:Application xmlns:s="http://www.default.com" xmlns:abc="www.mydomain.com">
   <abc:Button text="Hello world" />
</s:Application>

But how would you do that in the browser when you're pulling in code from different libraries? Where do I define global objects and how do I make them unique? Do I do something like:

window["com.mydomain.controls.MyApplication"];

I've seen libraries do something like:

GalleryWidget = function() { 
      var version = 1.2.3;
      var getGallery = function() { //do stuff };
}

But what if there is another GalleryWidget some where? Sorry if this is a beginner question.

Addendum
Maybe if I paste some code it will clear things up. Is there any problems with the following:

window.VideoPlayer = {}; // write my class, etc
window.myVideoPlayer = new VideoPlayer();
window.submitForm = function() {}; //etc
window.parse = function() {}
JSON.parseXML = function(zml) {};
document.write = function() {};

UPDATE 2:
I found a web page that is using Yahoo Global Objects:

var $D  =  YAHOO.util.Dom;
var $E  =  YAHOO.util.Event;
var $A  =  YAHOO.util.Anim;
var $M  =  YAHOO.util.Motion;
var $EA =  YAHOO.util.Easing;
var $DD =  YAHOO.util.DD;
var $C  =  YAHOO.util.Connect;
var $   =  $D.get;

YAHOO.namespace ("Smb.Asteroids.Logger");
YAHOO.Smb.Asteroids.Logger = {
    Log : function(e) {
        if (typeof console !== 'undefined') {
            console.log(e);
        }
    }
}
var $LOG = YAHOO.Smb.Asteroids.Logger.Log;
    YAHOO.namespace('Smb.Asteroids');
var YSA = YAHOO.Smb.Asteroids;

YSA.Nav = {
    isNavNorth : false,

    init : function() {
        // For the first visit, subscribe to the layout(template) change event
        // When user changes template from the ribbon, we need to re-init this JS, based on the new templates settings. 
        if (YSA.Nav.isFirstVisit) {
            YSA.Nav.isFirstVisit = false;
            if (YSA.UiMgr) {
                YSA.UiMgr.Layout.onChange.eventObj.subscribe(
                    function() { YSA.Nav.init() });
            }
        } else {
            YSA.Nav.clearSubNavStyles();
        }

        YSA.Nav.initNavSettings();
        var navDiv = $('navigation');
        if (! $D.hasClass(navDiv, 'sub_dynamic')) {
            return;
        }
        YSA.Nav.initNavSettings();
        var triggers = $D.getElementsByClassName('trigger', '', navDiv);
        $E.on(triggers, 'mouseover', this.mouseOverTrigger);
        $E.on(triggers, 'mouseout', this.mouseOutTrigger);
        var toggles = $D.getElementsByClassName('toggle', 'a', navDiv);
        $E.on(toggles, 'click', this.toggleClicked);
        var triggers = $D.getElementsByClassName('mainNav', '', navDiv);
        $E.on(triggers, 'mouseover', this.mouseOverMainNav);
    }
};

$E.on(window, 'load', YSA.Nav.init, YSA.Nav, true); 

I've truncated a lot of the code. It is based on Yahoo YUI framework here but it looks like the page is down. Way back machine should show it.

Anyway, it answers some questions I had. But I noticed that this is based on framework 2. They have framework 3 that seems to get rid of namespaces. So that leaves more questions.

  • I think you've contradicted yourself. – David Cowden Jan 12 '17 at 8:42
  • 2
    What do you mean? – 1.21 gigawatts Jan 12 '17 at 8:43
  • @DavidCowden I think he's asking if there is a way to prevent subsequent re-assigning of the variable containing his application – Orangesandlemons Jan 12 '17 at 9:57
  • 1
    Sure, but even languages with formal support for modules don't really solve this. Some don't compile, some it's first come first serve, and other's it's a first in last out stack. While languages may differ in how they handle the scenario, you still need to make sure that none of your namespaces conflict. – David Cowden Jan 12 '17 at 10:01
  • But there are strategies for reducing the chances of conflicts with other libraries/code, especially for third-party users. In fact, the use of the application 'parent' variable is to reduce these sort of problems. – Orangesandlemons Jan 12 '17 at 10:09
1

From your code example, it seems you are not making a JavaScript library but a simple application.

For this, you are unnecessarily using the window namespace. This is reserved for global objects and by adding so many variables here you are only looking for trouble.

In JavaScript, you can easily ensure your code does not conflict with other libraries or code by putting it inside an anonymous self-executing function:

(function () {

// Put your code here

})();

Everything inside this function will effectively be isolated and you do not have to worry about variable names, just don't use the window object to declare a variable. So your example would turn into something like this:

(function () {

var VideoPlayer = {}; // write my class, etc
var myVideoPlayer = new VideoPlayer();
var submitForm = function() {}; //etc
var parse = function() {}
var parseXML = function(zml) {};
var write = function() {}; 

})();

If you really DO WISH to assign something to the window object - and you only want this if you are building a library or in rare few other cases - it's up to you to ensure there are no conflicts. There is really no way to programmatically solve this problem, but you could tell the user something is wrong:

if (window.myLibrary) {
  throw "Error: you already have a library using myLibrary namespace. Please resolve the conflict."
} else {
  window.myLibrary = function () {} // Get the party started
}

Also, stick with creative and unused names (hint: Google is your friend).

0

But what if there is another GalleryWidget some where?

While you can never be 100% sure, choosing a namespace which is unlikely to be used by something will help prevent this problem. Your application's official name would normally do, unless it is very generic. So GalleryWidget is generic, jquery is unlikely to be duplicated for anything other than that library.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.