It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened,
visit the help center.
Closed 7 years ago.
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();
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.
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
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.
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.
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.