Javascript pseudo Array Implementation Method

Source: Internet
Author: User

This article will answer the last question about pseudo arrays mentioned in the general circular Traversal method forEach in javascript.
What is a pseudo array?
You can use Array. prototype. slice to convert an object with the length attribute to a real Array.
There are many such objects, especially arguments objects, as well as getElementsByTagName, document. childNodes, and so on. All of them return NodeList objects which belong to pseudo arrays.
We can use Array. prototype. slice. call (fakeArray) to convert a pseudo Array to a real Array object.
Here is an example: Copy codeThe Code is as follows: var fakeArray01 = {0: 'A', 1: 'B', length: 2}; // This is a standard pseudo array object.
Var arr01 = Array. prototype. slice. call (fakeArray01 );
Alert (arr01 [0]); //
Var arr02 = []. slice. call (fakeArray01 );
Alert (arr02 [0]); //

Slice can be used to obtain array fragments. It returns a new array without modifying the original array.
In the example, we can see that fakeArray is successfully converted into an Array object. Maybe you want. prototype. slice. the call statement is unfamiliar. In fact, we can also use []. slice. the call method achieves the same effect. Why do we need to implement it in prototype mode? The answer is to execute the program in prototype mode with higher efficiency and more beautiful code.
Implementation of pseudo Array
Let's take a closer look at the implementation of pseudo array.
Let's look at some special use cases:Copy codeThe Code is as follows: var fakeArray01 = {a: 'A', B: 'B', length: 2}; // No value corresponding to the length subscript
Var arr01 = Array. prototype. slice. call (fakeArray01 );
Alert (arr01 [0]); // undefined
Var fakeArray02 = {0: 'A', 1: 'B', length: 'num'}; // length is not a numerical value.
Var arr02 = Array. prototype. slice. call (fakeArray02 );
Alert (arr02 [1]); // undefined

Similarly, fakeArray01 and fakeArray02 are converted into real arrays, but the values in the arrays are undefined.
View the source code of the V8 engine array. js to simplify the internal implementation of slice:Copy codeThe Code is as follows: function slice (start, end ){
Var len = ToUint32 (this. length), result = [];
For (var I = start; I <end; I ++ ){
Result. push (this [I]);
}
Return result;
}

We can see that slice does not need this to be of the array type, but only needs to have the length attribute. And the length attribute can not be of the number type. If the value cannot be converted, ToUnit32 (this. length) returns 0.
According to the above conclusions, we can conclude that fakeArray01 is converted to an array with lenth 2, its values are initialized to undefined, and fakeArray02 is converted to an array with length 0, undefined is returned for elements with a natural access subscript of 1.
IE Problems
All the problems can be explained for the standard browser slice implementation, but IE encountered problems when handling NodeList. In IE, NodeList cannot be converted to a real array, and an error occurs. Why? Strictly speaking, an abstract class Arraioid is defined in IE. Both Array and Arguments inherit this class, so slice can be used. However, DOM objects are connected to JScript through COM, which is invalid during slice detection.
Jquery and pseudo Array
Jquery uses a large number of pseudo arrays internally. It can be said that the entire Jquery object is built on the basis of the pseudo array, so let's look at some practical use of Jquery:Copy codeThe Code is as follows: <! Doctype html public "-// W3C // dtd html 4.01 Transitional // EN">
<Html>
<Head>
<Title> fakeArray </title>
<Meta http-equiv = "content-type" content = "text/html; charset = UTF-8">
<Script src = "jquery-1.4.2.js" type = "text/javascript"> </script>
<Script>
$ (Document). ready (function (){
Var body = $ ("body ");
Alert (body. get (0). tagName );
});
</Script>
</Head>
<Body>
<Div id = "test"> </div>
</Body>
</Html>

Let's take a look at its internal implementation principles:Copy codeThe Code is as follows: jQuery. fn = jQuery. prototype = {
Init: function (selector, context ){
Var match, elem, ret, doc;
// Handle $ (""), $ (null), or $ (undefined)
If (! Selector ){
Return this;
}
// Handle $ (DOMElement)
If (selector. nodeType ){
This. context = this [0] = selector;
This. length = 1;
Return this;
}
// The body element only exists once, optimize finding it
If (selector = "body "&&! Context ){
This. context = document;
This [0] = document. body;
This. selector = "body ";
This. length = 1;
Return this;
}
//......
},
Get: function (num ){
Return num = null?
// Return a 'clean' array
This. toArray ():
// Return just the object
(Num <0? This. slice (num) [0]: this [num]);
}
}

Finally, Let's explain the execution details of the program. Before that, we have to talk about some internal aspects of Jquery.
Users who have used Jquery should know the $ () function, which is represented by the Jquery selector. We may use the $ () function to select elements on the page (the specific syntax can be the Jquery help document parameter ). In fact, when we execute the $ () function, the program executes the init method listed above. Let's take a look at the events that occurred when $ (document) was called:Copy codeThe Code is as follows: // $ (document)
Init: function (selector, context ){
Var match, elem, ret, doc;
// Handle $ (DOMElement): Process DOM elements,
If (selector. nodeType ){
This. context = this [0] = selector; // assign the selector value to attribute 0, which is the document object.
This. length = 1; // create a pseudo array and update the subscript.
Return this; // return the Jquery object
}
//......
}

$ ("Body") is the same principle.
We know that all operations in Jquery return Jquery objects. How can we get the corresponding dom object? Jquery provides us with a get method, this function is used to obtain DOM objects from jquery objects. As a result, the body is available. get (0), why is get (0) instead of get (), because all Jquery operations are performed on arrays. Therefore, in the get method, we need to pass a lower value to obtain the specific element. Now let's take a look at the specific implementation of the get method:Copy codeThe Code is as follows: get: function (num ){
Return num = null?
// If there is no num, the DOM array is directly returned.
This. toArray ():
// If the specified num is used, the system returns the element of the specified underlying object.
// This. slice is another method of jquery. It actually calls Array. prototype. slice internally to convert a pseudo Array to a real Array.
(Num <0? This. slice (num) [0]: this [num]);
}

This is where the pseudo array is. I think it's almost the same.
Note: if you have the opportunity, there may be a series "Beyond Jquery" in the future, which will analyze the details of Jquery's internal execution. However, Jquery's various internal tricks are not very understandable, so this is a problem in the future.
Refer:
Http://lifesinger.org/blog/2010/05/array-prototype-slice/

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.