Friends who have used jquery know that his powerful chain-like operation, convenient, concise, easy to understand, as follows
$ ("has_children"). Click (function () {$ (this). AddClass (" Highlight "). Children ("a"). Show (). End (). siblings (). Removeclass ("Highlight "). Children ("a"). Hide ();});
How is the chain operation of 1.jQuery implemented?
2. Why should I use chain-like operation?
Chained operation
Principle believe Baidu a lot of, in fact, chain operation is only through the method of the object finally
Return the object back, of course, the object can continue to invoke the method, so you can chain-operated. So, simply implement one:
//define a JS classfunctionDemo () {}//extend its prototype.Demo.prototype ={setName:function(name) { This. Name =name; return This; }, GetName:function () { return This. Name; }, Setage:function(age) { This. Age =Age ; return This; }}; ////Factory functionfunctionD () {return NewDemo ();}//to implement a chained invocationD (). SetName ("CJ"). Setage (+). SetName ();
But...... Why do you use it?
General explanation: Save code, code looks more elegant.
For example, if you don't have a chain, you might want to write code like this:
document.getElementById ("Ele"). DoSomething ();d Ocument.getelementbyid ("Ele"). Dootherthing ();
This code calls two times document.getElementById to get the elements of the DOM tree, which consumes a large number, and writes two lines, and the chain simply writes a line, saving the code ...
But we can also use the cache element ah. Like what:
var ele = document.getElementById ("ele"); ele.dosomething (); ele.dootherthing () ;
And the two lines are not much more code than the line, and even the corresponding package makes the code more.
The worst thing is that all of the object's methods return the object itself, meaning there is no return value, which is not necessarily appropriate in any environment.
For example, we want to make a super-large integer BigInteger (meaning that if you use JavaScript number to save an integer that might overflow), would it be appropriate to extend his method of operation in a chained way?
For example, the Operation 31415926535 * 4-271828182, if the design of a chain style method may be this:
var result = (new BigInteger ("31415926535")). Multiply (new BigInteger ("4")). Subtract ( New BigInteger ("271828182")). Val (); Console.log ("result = =" + result);
This may seem elegant, but what if we want the middle result? May be written like this:
var New BigInteger ("31415926535"); var result1 = biginteger.multiply (new BigInteger ("4")). Val (); var result2 = biginteger.subtract (new BigInteger ("271828182")). Val (); Console.log (" RESULT1 = = "+ Result1 +", result2 = = "+ result2);
This does not seem to be elegant at all, and no chain-like operation is no different!
So what if the requirements are the original BigInteger cannot be changed? Well, chained operations don't seem to meet this requirement.
jquery focuses on DOM object manipulation, and DOM operations are represented on the page, not in JavaScript by return values, but not in the same way, and we most likely need to return intermediate process values through JavaScript for another use.
In the design, we need to consider the advantages and disadvantages of the chain, because others use the chain, so the use of chain, may not be a good solution.
So why should we use chain-like operation?
for a better asynchronous experience
JavaScript is a non-blocking language, so instead of blocking, he can't block, so he needs to drive through events, asynchronously to do something that needs to block the process.
But asynchronous programming is a crazy thing ... It doesn't matter when the runtime is detached, but it's also separate when writing code ...
What are the common asynchronous programming models?
callback function The so-called callback function, meaning that the function is registered somewhere in the system, let the system know the existence of the function, and then later, when an event occurs, then call this function to respond to the event.
function f (num, callback) { if(num<0) { alert ("Call lower function processing!") ); Alert ("The score cannot be negative, enter an error!") ); } Else if (num==0) { alert ("Call low-level function processing!") ); Alert ("The student may not have taken the exam!") "); } Else { alert ("Call high-level function handling!") ); SetTimeout (function() {callback ();}, +);} }
Here callback is the callback function. You can see that callback is called only if NUM is a non-negative number.
But the problem, if we do not look inside the function, we do not know when the callback will be called, under what circumstances to invoke, there is a certain coupling between the code, the process will also produce some confusion.
Although a callback function is a simple and easy-to-deploy way to implement async, it is not good enough from the programming experience.
functionEventtarget () { This. Handlers = {};} Eventtarget.prototype={constructor:eventtarget, AddHandler:function(type, handler) { This. handlers[type] = []; }, Fire:function(){ if(!event.target) {Event.target= This; } if( This. handlers[event.typeinstanceofArray]) { varHandlers = This. Handlers[event.type]; for(vari = 0, Len = handlers.length, i < Len; i++) {Handlers[i] (event); }}, RemoveHandler:function(type, handler) {if( This. Handlers[type]instanceofArray) { varHandlers = This. Handlers[type]; for(vari = 0, le = handlers.length; i < Len; i++){ if(Handlers[i] = = =handler) { Break; }} handlers.splice (I,1); } }};
Above is the custom event implementation in JavaScript advanced programming. So we can use AddHandler to bind event handlers, fire to trigger events, and RemoveHandler to delete event handlers.
Although the events are decoupled, the sequence of processes is more chaotic.
I think the most commendable thing about chained operation is that it solves the problem that the execution flow of asynchronous programming model is not clear. jquery in $ (document). Ready is a great illustration of this idea. Domcotentloaded is an event that most of jquery's operations do not work until the DOM is loaded, but jquery's designers do not treat him as an event, but instead turn to a "select object, manipulate it" mentality. $ selects the Document object, and ready is the way it operates. The process problem is very clear, and the way to the back of the chain is to be executed.
(function(){ varisready=false;//determine if the Ondomready method has been executed varreadylist= [];//put the method that needs to be executed first in this array varTimer//Timer Handleready=function(FN) {if(IsReady) Fn.call (document); ElseReadylist.push (function() {returnFn.call ( This);}); return This; } varondomready=function(){ for(vari=0;i<readylist.length;i++) {readylist[i].apply (document); } readylist=NULL; } varBindready =function(evt) {if(IsReady)return; IsReady=true; Ondomready.call (window); if(Document.removeeventlistener) {Document.removeeventlistener ("Domcontentloaded", Bindready,false); }Else if(document.attachevent) {document.detachevent ("onReadyStateChange", Bindready); if(Window = =window.top) {clearinterval (timer); Timer=NULL; } } }; if(Document.addeventlistener) {Document.addeventlistener ("Domcontentloaded", Bindready,false); }Else if(document.attachevent) {document.attachevent ("onReadyStateChange",function(){ if((/loaded|complete/). Test (Document.readystate)) Bindready (); }); if(Window = =window.top) {Timer= SetInterval (function(){ Try{IsReady|| Document.documentElement.doScroll (' left ');//under IE can execute DoScroll judge whether the DOM is loaded}Catch(e) {return; } bindready (); },5); } }})();
The above code cannot be used with $ (document). Ready, and should be window.ready.
The asynchronous programming model in Commonjs also continues the idea that each asynchronous task returns a Promise object that has a then method that allows the callback function to be specified.
So we can write this:
F1 (). Then (F2). then (F3);
jquery chained operation [GO]