I am not able to understand how jQuery chaining wo

2020-06-28 15:55发布

I am not able to understand how jQuery chaining works.

jQuery("div").attr("id", "_id")
    .hide()
    .show();

I did something like chaining, but I'm not sure if it's the same logic that jQuery uses.

var fun = (function (parma) {
return function () {
    return {
        start: function () {
            console.log("start");
            return this;
        },

        mid: function () {
            console.log("mid");
            return this;
        },

        last: function () {
            console.log("last");
            return this;
        }
    }
}

})();

// Working
fun().start()
    .mid()
    .last();

5条回答
欢心
2楼-- · 2020-06-28 16:23

If I remember correctly, jQuery uses a classic approach to chaining within it’s prototypes with one exception, it also have an enhanced constructor in it’s init prototype. Here is a simple pattern:

function myQuery(elem){
   return new myQuery.prototype.init(elem);
};

myQuery.prototype.init = function(elem) { // the constructor "enhanced"
    this.elem = elem;
};

// now copy the myQuery prototypes into init.prototype
myQuery.prototype.init.prototype = myQuery.prototype;

// here comes the chainable prototypes:

myQuery.prototype.start = function() {
    this.elem.className = 'start';
    return this; // returning the instance allows further chaining
};

myQuery.prototype.finish = function() {
    this.elem.className = 'finish';
    return this;
};

// now use it
myQuery(document.body).start().finish();

Chaining prototypes is more effective, because you can reuse the prototype methods for each instance. jQuery is often initialized many times in a document, and if you created a new object with all chainable methods each time it would add unnecessary overhead and possible leaks.

查看更多
小情绪 Triste *
3楼-- · 2020-06-28 16:25

Think of it like this:

var myLib = {
    foo: function() {
        alert("FOO!");
        return this;
    },
    bar: function() {
        alert("BAR!");
        return this;
    }
}

myLib.foo().bar();

jQuery doesn't do it exactly like this, but this is one way to get a chaining functionality. This particular one doesn't store information about the current object.

The jQuery object has methods that return the modified jquery object, allowing you to call more methods on it.

查看更多
Rolldiameter
4楼-- · 2020-06-28 16:28

If the return value of a function is an object that has a method, you can call that method immediately. Simple as that.

Since you're returning this, you're returning the same object that the previous method was called on. That means you're returning an object with all the same methods.


Think of it this way:

var f = {
    foo: function() {
             console.log("foo");
             return b;
         }
};

var b = {
    bar: function() {
             console.log("bar");
             return f;
         } 
};

Here we have two objects.

  • The f object has a method called foo that returns the b object.
  • The b object has a method called bar that returns the f object.

Because of this, after calling foo, we can call bar, and vice versa.

f.foo().bar().foo().bar(); // etc

But because f doesn't have bar and b doesn't have foo, we can never call the same method twice.


But what if we only had one object, that had both methods, and both methods always returned the same original object?

var fb = {
    foo: function() {
             console.log("foo");
             return fb;
         },
    bar: function() {
             console.log("bar");
             return fb;
         }
};

Now we're always returning an object that has both the foo and bar methods, so we can call either method.

fb.foo().bar().bar().bar().foo().foo().bar();

So now the only real difference is that we are returning fb instead of this, but it doesn't matter since they're the same object. The code above could do return this; and it would behave the same.

It would matter if you wanted to create several instances of the object, but that's a question of object orientation techniques, not method chaining.

查看更多
叼着烟拽天下
5楼-- · 2020-06-28 16:35

The return on every function is a jQuery object. Each jQuery object will have the reference to all the function such as show/hide and so you can simply write

jQuery("#myDiv")         //returns a jQuery object 
    .attr("id", "_id")   //sets the ID and returns the jQuery object
    .hide()              //Hides the element with ID myDiv and returns jQuery object
    .show();             //show the element with ID myDiv and returns jQuery object
查看更多
我欲成王,谁敢阻挡
6楼-- · 2020-06-28 16:40

Almost every jQuery function will also return a jQuery object. As a result, you're able to run jQuery functions on each individual returned object.

By writing chained code, you not only save time but also improve performance. Without forcing the computer to seek and use a specific node, operating on a returned object is far more efficient than starting another instance.

查看更多
登录 后发表回答