最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How does jQuery accomplish chaining of commands? - Stack Overflow

programmeradmin12浏览0评论

I consider myself (at best) a mid-level JavaScript guy...and of course...I want to understand HOW some things are acplished so I can write better code. As such, I've been looking under-the-hood of jQuery trying to uderstand it a little more about how certain things are acplished.

For example:
jQuery handles the case where IE and Opera return items by name instead of ID by doing the following:

// HANDLE: $("#id")
else 
{
    var elem = document.getElementById( match[3] );

    // Handle the case where IE and Opera return items
    // by name instead of ID
    if ( elem && elem.id != match[3] )
        return jQuery().find( selector );

    // Otherwise, we inject the element directly into the jQuery object
    var ret = jQuery( elem || [] )
    ret.context = document;
    ret.selector = selector;

    return ret;
}

...okay that's easy!

But a typical line of jQuery code chains a series of mands together:

$('#someElementId').fadeIn().css({ ...Some CSS Properties ... });

Now...I 'think' the chaining portion is handled in the following area:

jQuery.extend = jQuery.fn.extend = function() { ... };

I'm bing through this area...and I see HOW a single mand is processed...but I don't really see WHERE or HOW a chain-of-mands are managed. So I am obviously missing something.

So My Question Is:

  1. How does jQuery implement chaining of selectors?

I consider myself (at best) a mid-level JavaScript guy...and of course...I want to understand HOW some things are acplished so I can write better code. As such, I've been looking under-the-hood of jQuery trying to uderstand it a little more about how certain things are acplished.

For example:
jQuery handles the case where IE and Opera return items by name instead of ID by doing the following:

// HANDLE: $("#id")
else 
{
    var elem = document.getElementById( match[3] );

    // Handle the case where IE and Opera return items
    // by name instead of ID
    if ( elem && elem.id != match[3] )
        return jQuery().find( selector );

    // Otherwise, we inject the element directly into the jQuery object
    var ret = jQuery( elem || [] )
    ret.context = document;
    ret.selector = selector;

    return ret;
}

...okay that's easy!

But a typical line of jQuery code chains a series of mands together:

$('#someElementId').fadeIn().css({ ...Some CSS Properties ... });

Now...I 'think' the chaining portion is handled in the following area:

jQuery.extend = jQuery.fn.extend = function() { ... };

I'm bing through this area...and I see HOW a single mand is processed...but I don't really see WHERE or HOW a chain-of-mands are managed. So I am obviously missing something.

So My Question Is:

  1. How does jQuery implement chaining of selectors?
Share Improve this question edited Dec 11, 2011 at 2:06 FishBasketGordo 23.1k4 gold badges59 silver badges92 bronze badges asked Dec 8, 2011 at 13:19 Prisoner ZEROPrisoner ZERO 14.2k21 gold badges101 silver badges147 bronze badges 4
  • 2 Each method returns the current or modified selection object. It's called Fluent Interface style. en.wikipedia/wiki/Fluent_interface#JavaScript – asawyer Commented Dec 8, 2011 at 13:24
  • Okay...that's cool. But can you please show AND explain where this is going on in the jQuery code? – Prisoner ZERO Commented Dec 8, 2011 at 13:26
  • The link has examples in multiple languages, including javascript. – asawyer Commented Dec 8, 2011 at 13:27
  • Okay...I see. If you identify WHERE this happens in the code and put it into an answer below (and maybe add some menting) then I can credit you. – Prisoner ZERO Commented Dec 8, 2011 at 13:33
Add a ment  | 

5 Answers 5

Reset to default 3

All the methods on a jQuery object will return a jQuery object.

In this particular example you can see them being created jQuery().find( selector ) and jQuery( elem || [] )

As per your ment:

This is from the example here: http://en.wikipedia/wiki/Fluent_interface#JavaScript With extra ments

var Car = function() {

        var speed, color, doors;

        this.setSpeed = function(speed) {
                this.speed = speed;
                **//Returns the reference to the calling `car` object** 
                return this; 
        };

        this.setColor = function(color) {
                this.color = color;
                **//Returns the reference to the calling `car` object** 
                return this; 
        };

        this.setDoors = function(doors) {
                this.doors = doors;
                **//Returns the reference to the calling `car` object** 
                return this; 
        };

};

// Fluent interface
**//Each method returns a reference to the object itself**
**//so the next method chain is refering back to the previous returned value**
**//ie - itself, the orginal object that started the call chain**
myCar = new Car();
myCar.setSpeed(100).setColor('blue').setDoors(5);

// Example without fluent interface
**// normal, non fluent style, where each method returns Void**
**// so you need to start with the object reference yourself each time**
myCar2 = new Car();
myCar2.setSpeed(100);
myCar2.setColor('blue');
myCar2.setDoors(5);

I will try to explain with an example. For this example you should open chrome developer console or firebug.

var $m = function() {
    return this;
};
$m.log = function(param) {
    console.log(param);
    return this;
};
$m.alert = function(param) {
    this.log('alerting: ' + param);
    alert(param);
    return this;
};
$m.log('start').alert('Sample message').log('end').log('success');

As you can see, every function returns this, which refers to $m for this example. This way I can chain as many methods as I want.

My understanding is this: Jquery functions return a reference to the relevant object when they execute, which is what allows you to chain operations together. So, if you perform an operation to find a div, the function returns a reference, allowing you to immediately chain another operation to the end of it.

Using return this; returns the parent OBJECT

var myObject = {
  a: function(){
    alert('a');
    return this; 
    //this == myObject, so returning myObject means 
    //the next function in the chain will call myObject.___
  },
  b: function(){
    alert('b');
    return this;
  }
}
myObject.a().b();//alerts 'a' then alerts 'b'
发布评论

评论列表(0)

  1. 暂无评论