Explanation of the proxy mode in JavaScript

Source: Internet
Author: User
Tags join json tag name tagname

1. Definition of proxy mode

Definition of proxy mode: Provides a proxy for other objects to control access to this object.

In proxy mode, an object acts as an interface of another object.

This mode looks like additional overhead, but it is very useful for performance considerations. The proxy acts as the guardian object of the ontology object and tries to make the ontology object do as little work as possible.

II. Applicable scenarios of proxy mode

The proxy mode can be used in the following scenarios:

Delay the instantiation of a large object;
Access remote objects;
Access control;
... ...
III. Proxy mode implementation

In proxy mode, one object acts as the interface of another object, so that the ontology object does as little work as possible.

/* =================== Ontology class ============================= */
Var Client = function (){};
Client. prototype = {
Add: function (){
// Add a function ......
},
Delete: function (){
// Delete the function ......
},
Update: function (){
// Modify the function ......
    }
};

/* = */
Var Proxy = function (){
This. client = new Client ();
};
Proxy. prototype = {
Add: function (){
Return this. client. add ();
},
Delete: function (){
Return this. client. delete ();
},
Update: function (){
Return this. client. update ();
    }
};
3.1 Virtual Proxy

If the Client class has many methods and most of them are large and complex, it will occupy a lot of CPU for the sake of instance. Isn't it better to instantiate this object when we need to use it? The virtual proxy delays the creation of objects with high overhead until they are actually needed.

Let's refactor the above code with a virtual proxy:

/* =================== Ontology class ============================= */
Var Client = function (){};
Client. prototype = {
Add: function (){
// Add a function ......
},
Delete: function (){
// Delete the function ......
},
Update: function (){
// Modify the function ......
    }
};


/* = */
Var Proxy = function (){
This. client = null;
};
Proxy. prototype = {
// Create an instance object only when necessary
_ Init: function (){
If (! This. client ){
This. client = new Client ();
        }
},
Add: function (){
This. _ init ();
Return this. client. add ();
},
Delete: function (){
This. _ init ();
Return this. client. delete ();
},
Update: function (){
This. _ init ();
Return this. client. update ();
    }
};
3.2 cache proxy

The cache proxy can provide temporary storage for some overhead computing results. In the next operation, if the passed parameters are the same as before, you can directly return the previously stored calculation results.

For example:

/* ===================== Ontology classes with high overhead ============================= */
Var calculate = function (){
Var result;

// Complex and massive computing .......

Return result;
};

/* = Cache proxy class = */
Var calculateProxy = (function (){
Var cache ={}; // cache calculation results

Return function (){
Var args = Array. prototype. join. call (arguments ,",");
If (args in cache ){
Return cache [args];
        }
Return cache [args] = calculate. apply (this, arguments );
    }
})();

/* ===================== Client implementation ============================= */
CalculateProxy (1, 2, 3, 4, 5); // The calculate function of the ontology is calculated and written to the cache.
CalculateProxy (1, 2, 3, 4, 5); // The calculate function of the ontology is not calculated, but directly returns the previously cached calculation results.
CalculateProxy (1, 2, 3); // The calculate function of the ontology is calculated and written to the cache.
By adding a cache proxy, the cardinate function of the ontology can focus on its own computing functions, while the cached amount function is implemented by the proxy object.

3.3 dynamically create a proxy using high-level functions

You can create a cache proxy for various computing methods by passing in higher-order functions. These methods are passed as parameters to a factory specifically used to create a cache proxy. In this way, we can create a cache proxy for addition, subtraction, multiplication, division, and so on. The code is as follows:

/*********** Product **********/
Var mult = function (){
Var result = 1;
For (var I = 0, l = arguments. length; I <l; I ++ ){
Result = result * arguments [I];
    }
Return result;
};
/********** Calculate and add **********/
Var plus = function (){
Var result = 0;
For (var I = 0, l = arguments. length; I <l; I ++ ){
Result = result + arguments [I];
    }
Return result;
};

/*********** Create a factory for the cache proxy **********/
Var createProxyFactory = function (fn ){
Var cache = {};

Return function (){
Var args = Array. prototype. join. call (arguments ,",");
If (args in cache ){
Return cache [args];
        }
Return cache [args] = fn. apply (this, arguments );
};
};

Var multProxy = createProxyFactory (mult );
Var plusProxy = createProxyFactory (plus );

**********/
MultProxy (1, 2, 3, 4, 5); // 120
PlusProxy (1, 2, 3, 4, 5); // 15
3.4 Other proxy modes

Agent mode has many variants, mainly including:

Remote proxy: provides a local representation of an object in different address spaces.
Protection proxy: used to control the access of objects with different permissions to the target object.
Intelligent reference proxy: instead of simple pointers, it performs some additional operations when accessing an object, such as calculating the number of times an object is referenced.
... ...
The proxy mode includes many sub-categories. The most common ones in JavaScript development are virtual proxy and cache proxy.

IV. Practical application of proxy mode

4.1 virtual proxy for image pre-loading

In Web development, because the image is too large or the network is poor, the image location is often blank for a period of time. A common practice is to use an image as the placeholder for the loading image, and then load the image asynchronously. After the image is loaded, insert it into the img node. This type of delayed initialization is suitable for virtual proxy.

Import the proxy object proxyimage. after the proxy object is completed, the uploaded chrysanthemum Image loading.gif is displayed, prompting you that the image is being loaded. As follows:

Var myImage = (function (){
Var imgNode = document. createElement ("img ");
Document. body. appendChild (imgNode );

Return {
SetSrc: function (src ){
ImgNode. src = src;
        }
};
})();

Var proxyImage = (function (){
Var img = new Image;
Img. onload = function (){
MyImage. setSrc (this. src );
};
Return {
SetSrc: function (src ){
MyImage. setSrc ("loading.gif ");
Img. src = src;
        }
};
})();

ProxyImage. setSrc ("yun_qi_img/1.jpg ");
Note: This code is excerpted from chapter 6th P92 of JavaScript design patterns and development practices.

4.2 Merge HTTP requests using a virtual proxy

Assume that when you click the delete tag button for the tag management function, the corresponding tag will delete the network request for the server tag. When you click the delete button multiple times in a short time, it is foreseeable that such frequent network requests will incur considerable overhead.

Solution: we can collect requests within a period of time and send them to the server at one time. For example, after two seconds, the tags to be deleted within two seconds are packaged and sent to the server.

/* ================= Ontology class for deleting tags =========================== */
Var deleteTag = function (tagName ){
// Network request and function implementation for deleting tags
//......
}

/* =================== The proxy class for deleting tags ========================= */
Var deleteTagProxy = (function (){
Var cache = [], // name of the tag to be deleted for a period of time
Timer; // timer

Return function (tagName ){
Cache. push (tagName );
If (timer) {// ensure that the started timer is not overwritten
Return;
        }

// Send the set of tags to be synchronized to the ontology after 2 seconds
Timer = setTimeout (function (){
DeleteTag (cache. join (","));

// Clear the timer
ClearTimeout (timer );
Timer = null;

// Clear the tag name set
Cache = [];
},2000 );
};
})();

/* =================== Interactive implementation of deleting tags ========================= */
/*
* The DOM structure of the tag deletion button is: <div class = "btn-delete-tag" data-tagName = "my-tag"> </div>
*/
Var deleteTagBtn = document. getElementByClassName ("btn-delete-tag ");

DeleteTagBtn. forEach (function (element, index ){
Element. addEventListener ("click", function (){

DeleteTagProxy (this. dataSet. tagName );

}, False );
});
4.3 cache proxy for ajax asynchronous request data

Paging is often required in projects. Theoretically, data on the same page needs to be pulled once in the background. After the pulled data is cached somewhere, you can directly read the data from the cache when you request the same page next time.

The cache proxy mode is applicable here.

/* =================== Ajax tool functions ============================= */
Function ajax (options ){
Options = options | {};
Options. type = (options. type | "GET"). toUpperCase ();
Options. dataType = options. dataType | "json ";
Var params = formatParams (options. data );

// Create XMLHttpRequest
If (window. XMLHttpRequest) {// IE6 + and modern browser
Var xhr = new XMLHttpRequest ();
} Else {// IE6 and earlier browsers
Var xhr = new ActiveXObject ('Microsoft. Xmlhttp ');
    }

// Receive data
Xhr. onreadystatechange = function (){
If (xhr. readyState = 4 ){
Var status = xhr. status;
If (status> = 200 & status <300 ){
Options. success & options. success (xhr. responseText, xhr. responseXML );
} Else {
Options. fail & options. fail (status );
            }
        }
    }

// Connect and send data
If (options. type = "GET "){
Xhr. open ("GET", options. url + "? "+ Params, true );
Xhr. send (null );
} Else if (options. type = "POST "){
Xhr. open ("POST", options. url, true );
Xhr. send (params );
    }
}

// Format parameters
Function formatParams (data ){
Var arr = [];
For (var name in data ){
Arr. push (encodeURIComponent (name) + "=" + encodeURIComponent (data [name]);
    }
Arr. push ("v =" + Math. random (). replace (".",""));
Return arr. join ("&");
}

/* ===================== Ajax asynchronous request paging data =============================== */
Var getPageContext = function (pageId ){
Var result;
Ajax ({
Url: "/test/index. php ",
Method: "get ",
DataType: "json ",
Data :{
Id: pageId
},
Success: function (response ){
Result = response;
        }
});
Return result;
};

/* = Cache proxy class = */
Var getPageContextProxy = (function (){
Var cache ={}; // cache calculation results

Return function (){
Var args = Array. prototype. join. call (arguments ,",");
If (args in cache ){
Return cache [args];
        }
Return cache [args] = getPageContext. apply (this, arguments );
    }
})();

/* ===================== Client implementation ============================= */
GetPageContextProxy (1); // request 1st page data to the server
GetPageContextProxy (2); // request a 2nd page data to the server
GetPageContextProxy (1); // Read 1st page data from the cache
V. Summary

The most common JavaScript development is virtual proxy and cache proxy.

Although the proxy mode is useful, in actual business development, you do not need to predict whether to use the proxy mode in advance. When it is found that it is inconvenient to directly access an object, it is not too late to write a proxy.

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.