52

YUI has a nice way of creating a namespace for your methods etc. in javascript.

Does jQuery have anything similiar?

9 Answers9

39

lpfavreau offers the solution to extend the jQuery object with your own methods (so that their functionality applies on the actual jQuery object context).

If you're looking to just namespace your code you can use the dollar symbol like this:

$.myNamespace = { .. };

or the "jQuery":

jQuery.myNamespace = { .. };

Be careful with the namespace you choose as this can overwrite existing jQuery methods (I'd suggest to first search in the jQuery code so that you don't).

You can follow this link: http://www.zachleat.com/web/2007/08/28/namespacing-outside-of-the-yahoo-namespace/

See how easy it is to create your own function to replicate what YUI does:

// include jQuery first.
jQuery.namespace = function() {
    var a=arguments, o=null, i, j, d;
    for (i=0; i<a.length; i=i+1) {
        d=a[i].split(".");
        o=window;
        for (j=0; j<d.length; j=j+1) {
            o[d[j]]=o[d[j]] || {};
            o=o[d[j]];
        }
    }
    return o;
};

// definition
jQuery.namespace( 'jQuery.debug' );
jQuery.debug.test1 = function()
{
    alert( 'test1 function' );
};
jQuery.debug.test2 = function()
{
    alert( 'test2 function' );
};
// usage
jQuery.debug.test1();
jQuery.debug.test2();
Community
  • 1
  • 1
Luca Matteis
  • 29,161
  • 19
  • 114
  • 169
12

This is how I create namespaces for my plugins:

(function ($) {
    // do not overwrite the namespace, if it already exists
    $.MyNamespace = $.MyNamespace || {};
    $.MyNamespace.MyPlugin = function () {/*here's the logic*/}
})($);

And then:

$.MyNamespace.MyPlugin ();
Wilk
  • 7,873
  • 9
  • 46
  • 70
  • That's all you really need. This can get a bit heavy/manual sometimes... And you'll probably want to automate some of that if you need your definitions to occur over multiple files. – 1nfiniti Jul 29 '13 at 21:28
  • Within the context of jQuery there are right and wrong ways to go about this. This is an example of the wrong way. Please see `jQuery.extend` and `jQuery.fn.extend`. – Madbreaks Jan 27 '17 at 17:35
5

jQuery has a bunch of plugins that extend the base functionality. There is this plugin for easy namespaces.

lpfavreau
  • 12,871
  • 5
  • 32
  • 36
4

The namespace plugin is COMPLETELY UNNECESSARY! The oldest trick in the world, the use of arguments.callee, Function.prototype and then calling a new Function instance, allows you to create nested namespaces with $.fn.extend!

Here is a plain and simple example:

    ;(function($){
    var options= {
        root: function(){ //you don't have to call it 'root', of course :)
            //identify the function from within itself with arguments.callee
            var fn= arguments.callee;

            //'this' at this level is the jquery object list matching your given selector
            //we equate fn.prototype to this 
            //thus when we call a new instance of root, we are returned 'this'
            fn.prototype= this;

            fn.value= function(){
                //Note: "new this" will work in the below line of code as well,
                //because in the current context, 'this' is fn;
                //I use fn to make the code more intuitive to understand;
                var context= new fn; 

                console.log(context, fn.prototype); //test
                return context.html(); //test
            }

            return this;
        }
    }

    //you can obviously append additional nested properties in this manner as well
    options.root.position= function(){
        var context= new this; //in this context, fn is undefined, so we leverage 'this'

        console.log(context, this.prototype); //test
        return context.offset(); //test
    }

    //don't forget to extend in the end :)
    $.fn.extend(options);

})(jQuery);

;$(function(){
    var div= $('div#div')
        .root();

    console.log(div.root.value());
    console.log(div.root.position());
});
  • 7
    `arguments.callee` and `arguments.caller` are deprecated and will cause errors in "strict mode" as of ECMAScript 5.[MDN](https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/callee) – ObjectiveCat Feb 13 '12 at 17:54
  • 15
    I dispute the claim that this is the oldest trick in the world. – mxcl Sep 08 '12 at 03:00
  • @MaxHowell Definitely not older than pulling a rabbit from a hat. – Yatrix Jan 08 '13 at 21:55
4

If you want to use jQuery in this manner:

$("*").namespace.do();

then currently there're no plugins doing that. (I can't find neither John Resig's jquery.space plugin which apparently stopped working in jQuery 1.4, nor Gilberto Saraiva plugin that apparently didn't work as expected). I would gladly take a look at John's function to see why it stopped working, and what can be done to make it work and quite frankly, it would be the best approach of creating uncluttered namespaces.

As per http://malnotna.wordpress.com/2009/01/12/jquery-namespace-support/ another approach is to do namespacing as (using jQuery.Modularize by Ariel Flesler):

$("*").namespace().do()

but such syntax isn't "pretty". We're also passing results from one function to another.

My approach to creating namespaces is not putting namespaces in the end, but at the beginning of $, so our $('*').namespace syntax becomes:

$.namespace("*").do()

Weirdly, I don't know why such approach isn't mentioned, as it easily allows you to create unclattered namespaces without overwriting already existing functions (by using $.sub()). Also, making it work doesn't require anything. So:

(function($){
    $.namespace = $.sub();
    $.fn.test = function(){ return 1 };              
    $.namespace.fn.test = function() { return 2};
})(jQuery);

console.log($('*').test(), $.namespace('*').test());

And you're ready to go.

eithed
  • 41
  • 1
2

Depending on what you're trying to do, jQuery's plugin architecture may be what you're looking for:

$.fn.myPlugin = function() {
  return $(this).each(function() {
    // do stuff
  });
};

or ...

$.fn.myPlugin = function() {
  var myNamespace = {
    // your stuff
  };
};

really it depends on what you're trying to do.

http://docs.jquery.com/Plugins/Authoring

rmurphey
  • 552
  • 3
  • 7
2

check out this blog: http://javascriptweblog.wordpress.com/2010/12/07/namespacing-in-javascript/

the self-invoking dynamic namespacing is what i've used before:

var myApp = {};
(function(context) {
    var id = 0;

    context.next = function() {
        return id++;
    };

    context.reset = function() {
        id = 0;
    } 
})(myApp); 

window.console && console.log(
    myApp.next(),
    myApp.next(),
    myApp.reset(),
    myApp.next()
); //0, 1, undefined, 0
Alp
  • 29,274
  • 27
  • 120
  • 198
nologo
  • 5,918
  • 3
  • 36
  • 50
1

All credit to @Diego Fluery, I just took his slide deck and made a runnable code prototype, but it might save you a few minutes if you go this route:

<!DOCTYPE html>
<html>
<head>
<script type="application/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="application/javascript">

    $(document).ready(function() {
        (function () {
            $.fn.AppRedirect = function() {
                this.sendRequest = parts.sendRequest;
                this.doRedirect = parts.doRedirect;

                return this;
            }

            var parts = {

                doRedirect: function() {
                    console.log('doRedirect');
                },

                sendRequest: function() {
                    console.log('sendRequest');
                }

            };
        })();

        $("body").AppRedirect().sendRequest();
        $("body").AppRedirect().doRedirect();
    });     

</script>
</head>
<body>
</body>
</html>
Ben Flynn
  • 18,524
  • 20
  • 97
  • 142
0

Working in jQuery 3.6.0

I know this question is ancient and this answer may not be scoped to the exact level the OP wanted. However, namespaces in jQuery at function level are simplified now.

Example:

$("body").off(".myNamespace"); /* prevent duplicate listeners in the namespace */
$("body").on("click.myNamespace", "tr.dtrg-start", function() {
...
}

https://api.jquery.com/event.namespace/

https://api.jquery.com/on/#event-names

Joe Johnston
  • 2,794
  • 2
  • 31
  • 54