The most amazing thing about jquery is the class array object, that is, the jquery object in the conventional saying. Note: In the jquery class library, jquery is a function that exists as a namespace. It has many static methods. Because the function is also an object, the object has its original type, and the jquery prototype method calls its static method abnormally and frequently. Its first prototype method is INIT, which is affected by the prototype class library. The init method can also be used as a constructor. Its new instance is the jquery object. In the prototype of the jquery namespace, there is also a property called jquery that plays a role in other class library versions. Because of its special name, it is also used to identify whether it is a jquery object. In other words, there are three places where methods and attributes can be added in a centralized manner. The jquery namespace is used to add static methods. The jquery prototype is used to add a prototype method. You only need to add the method based on extend, jquery. prototype. init instance (jquery object), which has fewer attributes, including length, prevobject, selector, and context. The prototype of the jquery. Prototype. init instance is moved to jquery. prototype. Next, let's follow the jquery idea to implement a class array object.
First, we need to define a class, called Eve, which is actually a factory.
VaR Eve = function () {return new Eve. Prototype. INIT (arguments );}
If an array is used and a number is input, an empty array with the same length as the number value is returned. If several parameters are input, these parameters will become elements of the returned array, if nothing is returned, an empty array is returned (this method must use the new operator ). Well, because our class array does not require 100% simulation, we will generate the class array according to its method 2.
Class arrays require length attributes and indexes. length is easy to handle, but we need to assign values to indexes one by one. If we add new elements at the beginning, we need to rearrange the indexes, which is terrible, low efficiency. However, we can use the push method of the array.
Setarray: function (ELS) {This. Length = 0; // set the length and re-index array. Prototype. Push. Apply (this, ELS); return this ;},
To ensure that the setarray method is used, we must ensure that Els is an array, Because array. Prototype. Push. Apply (this, ELS) is used in it, and the array does not exist? As for the push method, it is simple to ensure that the caller has the Length attribute. The makearray below converts a non-array object to an array object. If it is null, it should be wrapped in.
Makearray: function (ARR) {// convert the input parameter to an array var ret = []; If (Arr! = NULL) {var I = arr. length; // a single element, but window, string, and function have the 'length' attribute, and add other judgment if (I = NULL | arr. split | arr. setinterval | arr. call) {RET [0] = arr;} else {try {ret = array. prototype. slice. call (ARR)} catch (e) {While (I) RET [-- I] = arr [I]; // clone array }}return ret ;},
With these two methods, we can write our constructor.
Init: function (OBJ) {This. setarray (this. makearray (OBJ); return this ;},
But this is the only way not to create a new instance, because this has some problems. The first two instances with this as Eve and the third returned this as Eve. Prototype. init.
<Br/> var Eve = function () {<br/> return new Eve. prototype. init (arguments); <br/>}< br/> Eve. prototype = {<br/> init: function (OBJ) {<br/> This. setarray (this. makearray (OBJ); <br/> return this; <br/>}, <br/> setarray: function (elems) {<br/> This. length = 0; // set length and re-index <br/> array. prototype. push. apply (this, elems); <br/> return this; <br/>}, <br/> makearray: function (ARR) {// converts the input parameter to a number. Group <br/> var ret = []; <br/> If (Arr! = NULL) {var I = arr. length; <br/> // a single element, but window, string, and function have the property of 'length, add other judgments <br/> if (I = NULL | arr. split | arr. setinterval | arr. call) {<br/> RET [0] = arr; <br/>}else {<br/> try {<br/> ret = array. prototype. slice. call (ARR) <br/>} catch (e) {<br/> while (I) RET [-- I] = arr [I]; // clone array <br/>}< br/> return ret; <br/>}< br/> try {<br/> var E = new Eve (1, 2, 3); <br/> alert (E ); <br/>} catch (ERR) {<br/> alert (ERR) <br/>}< br/>
RunCode
No? The makearray method cannot be found. In other words, the eve. Prototype. init instance cannot call the eve prototype method. If jquery is used, the jquery object cannot call the prototype method of its jquery namespace object. The solution is simple, and the two prototypes overlap directly. The method for adding a prototype for a namespace object is to add a prototype for its real body.
Eve. Prototype. init. Prototype = Eve. Prototype;
<Br/> var Eve = function () {<br/> return new Eve. prototype. init (arguments); <br/>}< br/> Eve. prototype = {<br/> init: function (OBJ) {<br/> This. setarray (this. makearray (OBJ); <br/> return this; <br/>}, <br/> setarray: function (elems) {<br/> This. length = 0; // set length and re-index <br/> array. prototype. push. apply (this, elems); <br/> return this; <br/>}, <br/> makearray: function (ARR) {// converts the input parameter to a number. Group <br/> var ret = []; <br/> If (Arr! = NULL) {var I = arr. length; <br/> // a single element, but window, string, and function have the property of 'length, add other judgments <br/> if (I = NULL | arr. split | arr. setinterval | arr. call) {<br/> RET [0] = arr; <br/>}else {<br/> try {<br/> ret = array. prototype. slice. call (ARR) <br/>} catch (e) {<br/> while (I) RET [-- I] = arr [I]; // clone array <br/>}< br/> return ret; <br/>}< br/> Eve. prototype. init. prototype = Eve. prototype; <br/> try {<br/> var E = new Eve (1, 2, 3); <br/> alert (E ); <br/>} catch (ERR) {<br/> alert (ERR) <br/>}< br/>
Run code
Let's add some methods to it to see what can be simulated.Program. In fact, we can use the index value above, that is, E [1], and 2 will pop up. However, tostring is a [object], rather than a sequence of numbers. There is a get () method in jquery. If no parameter is added, the array in it can be taken out. We will assign its tostring method to its Eve. prototype.
Tostring: function () {// returns a string var array = array. prototype. slice. call (this); Return array. tostring () ;}, get: function (Num) {return num === undefined? Array. Prototype. Slice. Call (this): This [num];}
<Br/> var Eve = function () {<br/> return new Eve. prototype. init (arguments); <br/>}< br/> Eve. prototype = {<br/> init: function (OBJ) {<br/> This. setarray (this. makearray (OBJ); <br/> return this; <br/>}, <br/> setarray: function (elems) {<br/> This. length = 0; // set length and re-index <br/> array. prototype. push. apply (this, elems); <br/> return this; <br/>}, <br/> makearray: function (ARR) {// converts the input parameter to a number. Group <br/> var ret = []; <br/> If (Arr! = NULL) {var I = arr. length; <br/> // a single element, but window, string, and function have the property of 'length, add other judgments <br/> if (I = NULL | arr. split | arr. setinterval | arr. call) {<br/> RET [0] = arr; <br/>}else {<br/> try {<br/> ret = array. prototype. slice. call (ARR) <br/>} catch (e) {<br/> while (I) RET [-- I] = arr [I]; // clone array <br/>}< br/> return ret; <br/>}, <br/> tostring: function () {// returns a string <br/> VaR array = array. prototype. slice. call (this); <br/> return array. tostring (); <br/>}, <br/> valueof: function () {return array. prototype. slice. call (this) ;}, <br/> Get: function (Num) {<br/> return num === undefined? Array. prototype. slice. call (this): This [num]; <br/>}</P> <p> Eve. prototype. init. prototype = Eve. prototype; <br/> try {<br/> var E = new Eve (1, 2, 3); <br/> alert (E ); <br/> alert (E [1]); <br/> alert (E. tostring (); <br/> alert (E. valueof (); <br/>} catch (ERR) {<br/> alert (ERR) <br/>}< br/>
Run code
Well, if you don't need to judge instanceof or typeof, you can't tell if it's an array or a class array. Let's add some array methods.
Shift: []. shift, push: []. push, sort: []. sort, POP: []. pop, splice: []. splice, Concat: []. concat, slice: []. slice, constructor: Eve, // *********************** Eve. tostring = function () {return "Function Array () {\ n [Variant Code] \ n }"}
<Br/> var Eve = function () {<br/> return new Eve. prototype. init (arguments); <br/>}< br/> Eve. prototype = {<br/> init: function (OBJ) {<br/> This. setarray (this. makearray (OBJ); <br/> return this; <br/>}, <br/> isarray: function (OBJ) {<br/> return object. prototype. tostring. call (OBJ) = "[object array]"; <br/>}, <br/> setarray: function (elems) {<br/> This. length = 0; // set the length and re-index <br/> Array. prototype. push. apply (this, elems); <br/> return this; <br/>}, <br/> makearray: function (ARR) {// convert the input parameter to an array <br/> var ret = []; <br/> If (Arr! = NULL) {var I = arr. length; <br/> // a single element, but window, string, and function have the property of 'length, add other judgments <br/> if (I = NULL | arr. split | arr. setinterval | arr. call) {<br/> RET [0] = arr; <br/>}else {<br/> try {<br/> ret = array. prototype. slice. call (ARR) <br/>} catch (e) {<br/> while (I) RET [-- I] = arr [I]; // clone array <br/>}< br/> return ret; <br/> }, </P> <p> inarray: function (ELEM, array) {<br /> For (VAR I = 0, length = array. length; I </P> <p> <button type = "button" Title = "runcode4" class = "runcode direct"> run the Code </button> </P> <p> in jquery, it also implements the EQ and index methods to obtain the index values of elements or elements, and implements several iterators of javascript1.6, each (foreach), map, and filter. This highly simulated class array object makes the jquery class library easily implement chained operations. But obviously, its filter and map methods are much more complicated than the implementation we found on the Internet, because as early as jquery1.0.1, pushstack methods were implemented to save and execute push, pop and other destructive operations before the array object. </P> <p> some people may feel very uncomfortable with the init method, because of its two types of this, two prototypes are required. That is, in addition to generating jquery objects, jquery init can also be used as domready. If it is a pure class array, we can completely remove it, but when generating class array objects, we must use the new operator. </P> <PRE class = "Brush: javascript; gutter: false; toolbar: true; collapse: True"> var Eve = function () {This. setarray (this. makearray (arguments); return this;} Eve. prototype = {isarray: function (OBJ) {return object. prototype. tostring. call (OBJ) = "[object array]";}, setarray: function (elems) {This. length = 0; // set the length and rearrange the index array. prototype. push. apply (this, elems); return this;}, makearray: Fu Nction (ARR) {// convert the input parameter to an array var ret = []; If (Arr! = NULL) {var I = arr. length; // a single element, but window, string, and function have the 'length' attribute, and add other judgment if (I = NULL | arr. split | arr. setinterval | arr. call) {RET [0] = arr;} else {try {ret = array. prototype. slice. call (ARR)} catch (e) {While (I) RET [-- I] = arr [I]; // clone array }}return RET ;}, inarray: function (ELEM, array) {for (VAR I = 0, length = array. length; I </PRE> <p>