Decoding jQuery – OOP and jQuery part 4

As a smaller series within Decoding jQuery series, OOP and jQuery will focus on jQuery internals and OOP concepts around it.

In this part, we will look into the function scope, jQuery chaining pattern and jQuery.fn.

1. function scope
We have seen jQuery object has been wrapped in many layers of functions. So why do we use function to define scope? It’s because JavaScript can’t use curly braces to do so. JavaScript variables have only function scope.

For instance, in order to make var jQuery in the example below private, we have to wrap it in a function.

function a() {
  var jQuery = "hellow world";
}
console.log(jQuery); // undefined

JavaScript functions have lexical scope, this means functions create their scope when they are defined, not when they are executed.

var jQuery = 'hi there';
var jQuery = (function() {
  console.log(jQuery);
  var jQuery = "hello world";
})();
// undefined

So if we run the above code, the value returned will be undefined instead of ‘hi there’. This means jQuery function creates its scope, it hasn’t read var jQuery = ‘hi there’. Therefore, to the jQuery function, jQuery was about to be (but not yet) defined in the function.

2. jQuery chaining pattern

When we look into the init method, one thing you may realize is that it always return this.

var jQuery = function( selector, context ) {
  // The jQuery object is actually just the init constructor 'enhanced'
  return new jQuery.fn.init( selector, context, rootjQuery );
}
jQuery.fn = jQuery.prototype = {
  init: function( selector, context, rootjQuery ) {
    //...
    return this;
    //...
  }
}

In jQuery, we can do chaining, which means we can add one method after another in a chain. The reason we can do so is because after each method executes, it returns the object. How did this happen?

First, let’s see how the this keyword works in an object:

var city = {
  name: 'beijing',
  getName: function() {
    return this.name;
  }
}
console.log(city.getName());

In the above example, the city name printed is beijing, which means this refers to the object city.

To go one step further, what if we only return the object?

var num = {
  value: 1,
  minus: function (n) {
   this.value -= n;
   return this;
  },
  plus: function (n) {
    this.value += n;
    return this;
  },
  getVal: function () {
    console.log(this.value);
  }
};
 
num.minus(2).plus(5).getVal();

3. jQuery.fn

So in the core.js, we can see a line saying: jQuery.fn = jQuery.prototype = {//…}

jQuery.fn = jQuery.prototype = {
  //...
}

When we do plugin development, we often use $.fn, which is jQuery.fn. So in face we are extending jQuery.prototype by adding method on top of it. Which is also why in most cases, it’s always good to return this.

(function( $ ){
  $.fn.fontcolor = function() {
    return this.each(function() {
      $(this).css("color", "orange"); 
    });
  };
})( jQuery );

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Technorati
  • Twitter
  • Yahoo! Bookmarks

About Shi Chuan

I am a web developer.
This entry was posted in JavaScript and tagged , . Bookmark the permalink.

3 Responses to Decoding jQuery – OOP and jQuery part 4

  1. Pomeh says:

    Thanks for this article and this serie. I love reading jQuery code source too, I learn a lot every time and it’s the best documentation we could find !

    But I have to disagree with you on your point 1 about function scope. Well not the entire point but I disagree with the phrase “This means jQuery function creates its scope, it hasn’t read var jQuery = ‘hi there’.”. I’ve done a test case on jsFiddle to explain why here: http://jsfiddle.net/pomeh/ynqBs/

    Hope it you find it useful (and correct too!). Don’t hesitate comment if you think I’ve said stupidity !

    Cheers !

  2. Shi Chuan says:

    @Pomeh: yea, depends on how people might interpret the word ‘undefined’. I think your example is clearer :)

  3. Pingback: Apprendre jQuery

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">