Monday, January 26, 2009

Namespace your JavaScript function and variable with jQuery

We all know that global variable are evil. Namespacing  your variables and methods is now considered a good practice and shows your awareness about the trends. Anyway, I thought how can I namespace my variables and methods in jQuery. Well, first off, I can easily extend jQuery with custom written plugins.

$.fn.extend({
  myNamespaced: function(myArg){
    return 'namespaced.' + myArg;
  }
});
jQuery().myNamespaced('A');
$().myNamespaced('A'); // Shorthand $()
// Outputs: namespaced.A

Now my functions are namespaced and would not conflict with any other already declared functions with the same name. This is great, but to access my functions or variables I have to call jQuery(). The code still looks like chaining not namespacing. To declare your variables or functions in jQuery namespace you can extend the core jQuery object itself using jQuery.extend() rather than jQuery.fn.extend().

$.extend({ 
  myNamespaced: function(myArg){ 
    return 'namespaced.' + myArg; 
  } 
}); 
jQuery.myNamespaced('A'); 
$.myNamespaced('A'); // Shorthand 
// Outputs: namespaced.A

As you can see, now I can call my functions and properties without parenthesis after jQuery object. Now my functions have a jQuery namespace and will not conflict with other functions that might have the same name.

TIP:
Use $.extend({}) to namespace your fields and methods.

8 comments:

  1. I am not sure I understand exactly. Let's say I wanted to use the namespace "BenNadel". How would I add nested methods to that?

    $.fn.extend({
    BenNadel: {
    Test: function(){ .... }
    }
    });

    Then, to access it, would I do:

    $( ... ).BenNadel.Test()

    Am I following this correctly?

    ReplyDelete
  2. This doesnt work, as the inner method Test() would have a wrong this variable, it would now points to the outer namespace hash. Any solution?

    ReplyDelete
  3. this makes no sense at all.

    ReplyDelete
  4. @chris, What's not making any sence ?!

    ReplyDelete
  5. jQuery.extend() its not the same as jQuery.fn.extend().

    first is used to add a "static" function to a jQuery namespace

    second is used to add a method to an element set, that jQuery is wrapping; there fore, using "this" in method provide u with matched set.

    and as William said if u use namespace with jQuery.fn.extend like: $.fn.kido.funbar() {
    this.show() // this will not point to a jQuery as it does if u omit "kido" namespace
    }
    im looking for the same solution :/

    ReplyDelete
  6. Nice practices!!! Thanks for the post!

    ReplyDelete
  7. I found a solution for the problem.
    It's not a very good solution, but it works.

    Here is it.

    $.fn.extend({
    NameSpace: function(method, arg1, arg2){
    var methods = {
    "meth1" : function(This){
    This.hide(); // use This instead of this
    },

    "meth2" : function(This, arg1, arg2){
    This.show();
    },

    "meth3" : function(This, arg1){
    This.hide(1000);
    },
    }
    methods[method](this, arg1, arg2 );
    //this.hide();
    }
    });

    If you want to call for example meth2 you will use.

    $("#id").NameSpace("meth2", arg1, arg2);

    ReplyDelete