JavaScript design mode Item 5-Chained call

Source: Internet
Author: User

1. What is a chained call

This is easy to understand, for example:

$(this).setStyle(‘color‘‘red‘).show();

The difference between a generic function call and a chained call: After the method is called, return this the object that is currently calling the method is returned.

 function Dog(){         This. run= function(){Alert"The dog is running ....");return  This;//Returns the current object, Dog}; This. eat= function(){Alert"After running, the dog is eatting ....");return  This;//Returns the current object, Dog}; This. sleep= function(){Alert"After eatting, the dog is running ....");return  This;//Returns the current object, Dog}; }//general method of invocation;/* var dog1 =new Dog ();    Dog1.run ();    Dog1.eat (); Dog1.sleep (); */    varDOG2 =NewDog (); Dog2.run (). Eat (). Sleep ();
2. Break-Chain Call

A chained call is actually two parts:

    • 1. manipulate the object (that is, the DOM element being manipulated, as in the example above)

    • 2. How to do it (specifically what to do, such as the SetStyle and show on the above example)

How to implement Operation object and Operation method

Create a generic $ function:

 function $(){    varelements = []; for(varI=0, len=arguments. length; i<len; i++) {varelement =arguments[i];if(typeofelement===' String ') {element = document.getElementById (element); }if(arguments. length==1){returnElement    } elements.push (Element); }returnelements;}

However, if you transform this function into a constructor, save those elements as an array in an instance property, and have all the methods defined in the prototype property of the constructor function return a reference to the instance that invokes the method, then it has the ability to chain-call. (Say so much, is at the end of each method return this; ),

I first need to $ change this function to a factory method, which is responsible for creating objects that support chained calls. This function should be able to accept parameters in the form of an array of elements so that we can use the same common interface as the original. Since then, it has the ability to make chained calls.

The following modifications are as follows:

( function(){     function _$(els){         This. elements = [];//save those elements as arrays in an instance property,         for(varI=0, Len=els.length; i<len; i++) {varelement = Els[i];if(typeofelement===' String ') {element = document.getElementById (element); } This. Elements.push (Element); }} _$.prototype = {each: function(FN){             for(varI=0, len= This. elements.length; i<len; i++) {Fn.call ( This, This. Elements[i]); }return  This;//In the last return of each method this;}, SetStyle: function(prop, Val){             This. each ( function(EL){El.style[prop] = val; });return  This;//In the last return of each method this;}, Show: function(){            varthat = This; This. each ( function(EL){That.setstyle (' Display ',' Block '); });return  This;//In the last return of each method this;}, Addevent: function(type, fn){            varAdd = function(EL){                if(Window.addeventlistener) {El.addeventlistener (type, FN,false); }Else if(window.attachevent) {El.addevent (' on '+type, FN); }            }; This. each ( function(EL){Add (EL); });return  This;//In the last return of each method this;}} window.$ = function(){        return New_$(arguments); }})();

In the last return this, the object that invokes the method is passed to the next method on the call chain.

3. Simulation of jquery bottom-chain programming
//block-level scopes//feature 1 when the program starts, the code executes directly.//feature 2 internal member variables cannot be accessed outside (except for variables without var modifier)( function(window, undefined){    //$ most commonly used objects returned to outside large program development general use ' _ ' as a private object (specification)     function _$(arguments){        //Implementation code ... Only the ID selector is implemented here        //Regular expression matching ID selector        varIdselector =/#\w+/; This. Dom;//This property accepts the resulting element        //If Match succeeds accept dom element arguments[0] = ' #inp '        if(Idselector.test (arguments[0])){ This. Dom = document.getElementById (arguments[0].substring (1)); }Else{Throw New Error(' arguments is Error! '); }    };//Extend a way to implement chained programming on the function class    Function. Prototype.method = function(methodName, fn){         This. prototype[methodname] = fn;return  This;//Key to chained programming}//Add some public methods to the prototype object of _$_$.prototype = {constructor: _$, Addevent: function(TYPE,FN){            //give you the Get element register event            if(Window.addeventlistener) {//FF                 This. Dom.addeventlistener (Type, FN); }Else if(window.attachevent) {//IE                 This. Dom.attachevent (' on '+type, FN); }return  This; }, SetStyle: function(prop, Val){             This. dom.style[prop] = val;return  This; }    };//Window first register a global variable with external relationswindow.$ = _$;//Write a method of preparation_$.onready = function(FN){         //1 instantiation out _$ Object Real Register to windowwindow.$ = function(){            return New_$(arguments); };//2 Execute incoming CodeFN ();//3 for chained programming_$.method (' addevent ', function(){            // nothing to do}). Method (' SetStyle ', function(){            // nothing to do}); };}) (window);//Entry window into the scope of the program$.onready ( function(){    varINP = $ (' #inp ');//alert (inp.dom.nodeName);    //alert ($ (' #inp '));Inp.addevent (' click ', function(){Alert' I've been clicked! '); }). SetStyle (' BackgroundColor ',' Red ');});
4. Use callback functions to obtain data from a method that supports chained invocation

Chained calls are well suited to evaluator methods, but it is inconvenient for accessor methods because each method returns this.

However, the workaround is there, and that is the callback function.

When a callback function is not used

//without CallbackWindow. API = window. API | | function(){    varName =' Jchen '; This. SetName = function(newName){name = NewName;return  This; }; This. GetName = function(){        returnName };};varo =NewAPI (); Console.log (O.getname ()); Console.log (O.setname (' Haha '). GetName ());

When using callback functions

//with CallbackWindow. API2 = window. API2 | | function(){    varName =' Jchen '; This. SetName = function(newName){name = NewName;return  This; }; This. GetName = function(callback){Callback.call ( This, name);return  This; };};varO2 =NewAPI2 (); O2.getname (Console.log). SetName (' Hehe '). GetName (Console.log);

When using the callback function Callback.call (this, name) is generally not a problem, but this example is used to Console.log, then there is a problem. The reason is that the this of the console is pointing to console instead of WINODW.

This problem is also very well solved. As follows:

//with CallbackWindow. API2 = window. API2 | | function(){    varName =' Jchen '; This. SetName = function(newName){name = NewName;return  This; }; This. GetName = function(callback){Callback.call ( This, name);return  This; };};varO2 =NewAPI2 ();varLog = function(para){Console.log (para);};o 2.getName (log). SetName (' Hehe '). GetName (log);
5. Summary

Chaining this style helps simplify code writing, makes your code more concise, easier to read, and avoids reusing an object variable multiple times.

Copyright NOTICE: This article is the original article, reproduced please specify: http://blog.csdn.net/i10630226

JavaScript design mode Item 5-Chained call

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.