This article answersJavaScript universal loop traversal method forEachThe last question about pseudo-arrays mentioned in
What is a pseudo-array
An object with a length attribute that can be converted into a real array.
There are many such objects, the arguments object is more special, and there are also those who call getElementsByTagName, etc. They all return NodeList objects and all belong to pseudo-arrays.
We can convert a pseudo-array into a real Array object by (fakeArray).
Let’s take a look at an example:
var fakeArray01 = {0:'a',1:'b',length:2};//This is a standard pseudo-array object
var arr01 = (fakeArray01);
alert(arr01[0]);//a
var arr02 = [].(fakeArray01);
alert(arr02[0]);//a
slice can be used to get array fragments, it returns a new array and does not modify the original array.
In the example, you can see that fakeArray has been successfully converted into an Array object. Maybe everyone is unfamiliar with this writing style, but we can actually achieve the same effect through []. This form. So why do we need to implement it through the form of prototype? The answer is that executing programs in the form of prototype is more efficient and the code is also more beautiful.
Implementation of pseudo-arrays
Let's take a closer look at the implementation of pseudo-arrays.
Let's look at some special use cases:
var fakeArray01 = {a:'a',b:'b',length:2};//No value corresponding to the length subscript
var arr01 = (fakeArray01);
alert(arr01[0]);//undefined
var fakeArray02 = {0:'a',1:'b',length:'num'};//length is not a numerical value
var arr02 = (fakeArray02);
alert(arr02[1]);//undefined
Similarly, fakeArray01 and fakeArray02 are converted into real arrays, but the values in the array are undefined
View V8 Engine The source code of slice can be simplified to:
function slice(start, end) {
var len = ToUint32(), result = [];
for(var i = start; i < end; i++) {
(this[i]);
}
return result;
}
It can be seen that slice does not need this to be of array type, it only needs to have the length attribute. And the length attribute can not be of type number. When it cannot be converted to a numeric value, ToUnit32() returns 0.
According to the above conclusion, it can be concluded that fakeArray01 is converted into an array with lenth of 2, and its values are initialized as undefined, fakeArray02 is converted into an array with length of 0, and naturally accessing elements with subscript of 1 returns undefined
IE's problem
All the problems can be explained for the standard browser slice implementation, but IE has problems dealing with NodeList. There will be an error if NodeList cannot be converted to a real array in IE. Why is this? Strictly speaking, an abstract class Arraioid is defined inside IE, and both Array and Arguments are inherited from this, so you can use slice. However, the DOM object is connected to JScript through COM, and it fails when slice detection.
Jquery and pseudo-array
Jquery uses a lot of pseudo-arrays inside. It can be said that the entire Jquery object is built on the basis of a pseudo-array, so let's take a look at some practical applications of Jquery:
<!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." type="text/javascript"></script>
<script>
$(document).ready(function(){
var body = $("body");
alert((0).tagName);
});
</script>
</head>
<body>
<div ></div>
</body>
</html>
The simplest program, okay, let's take a look at its internal implementation principle:
= = {
init: function( selector, context ) {
var match, elem, ret, doc;
// Handle $(""), $(null), or $(undefined)
if ( !selector ) {
return this;
}
// Handle $(DOMElement)
if ( ) {
= this[0] = selector;
= 1;
return this;
}
// The body element only exists once, optimize finding it
if ( selector === "body" && !context ) {
= document;
this[0] = ;
= "body";
= 1;
return this;
}
//... ...
},
get: function( num ) {
return num == null ?
// Return a 'clean' array
() :
// Return just the object
( num < 0 ? (num)[ 0 ] : this[ num ] );
}
}
Finally, let's explain the execution details of the program. But before that, we have to talk about some things inside Jquery.
Users who have used Jquery should know the $() function, which is the selector representative of Jquery. We may use the $() function to select elements in the page (the specific syntax can be parameterized by Jquery help document). In fact, when we execute the $() function, the program executes the init method listed above. Let’s take a look at the events that occur when calling $(document):
//$(document)
init: function( selector, context ) {
var match, elem, ret, doc;
// Handle $(DOMElement) : handles DOM elements,
if ( ) {
= this[0] = selector; // Assign a selector value to attribute 0, and it is the document object at this time
= 1; //Create a pseudo-array and update the subscript
return this; //Return the Jquery object
}
//... ...
}
$("body") is the same, I won't say more.
We know that all operations in Jquery return Jquery objects, so how do we get the corresponding dom object? Jquery provides us with a get method, which is specially used to obtain DOM objects from jquery objects. Therefore, there is (0). Why is it get(0) instead of get() again, because all operations in Jquery are performed for arrays. Therefore, in the get method, we need to pass a subscript value to get the specific element. Now it's time to look at the specific implementation of the get method:
get: function( num ) {
return num == null ?
//If there is no num, return the DOM array directly
() :
//If the specified num is returned, the element with the specified subscript is returned
//It is another method of jquery. It is actually called to convert a pseudo array into a real array
( num < 0 ? (num)[ 0 ] : this[ num ] );
}
That's all about pseudo-arrays, I think it should be almost done.
Note: If you have the opportunity, a "Beyond Jquery" series may be released in the future, which will specifically analyze the internal execution details of Jquery. However, since Jquery has various evil techniques, it is not very clear that this is a future problem.
refer to:
/blog/2010/05/array-prototype-slice/
What is a pseudo-array
An object with a length attribute that can be converted into a real array.
There are many such objects, the arguments object is more special, and there are also those who call getElementsByTagName, etc. They all return NodeList objects and all belong to pseudo-arrays.
We can convert a pseudo-array into a real Array object by (fakeArray).
Let’s take a look at an example:
Copy the codeThe code is as follows:
var fakeArray01 = {0:'a',1:'b',length:2};//This is a standard pseudo-array object
var arr01 = (fakeArray01);
alert(arr01[0]);//a
var arr02 = [].(fakeArray01);
alert(arr02[0]);//a
slice can be used to get array fragments, it returns a new array and does not modify the original array.
In the example, you can see that fakeArray has been successfully converted into an Array object. Maybe everyone is unfamiliar with this writing style, but we can actually achieve the same effect through []. This form. So why do we need to implement it through the form of prototype? The answer is that executing programs in the form of prototype is more efficient and the code is also more beautiful.
Implementation of pseudo-arrays
Let's take a closer look at the implementation of pseudo-arrays.
Let's look at some special use cases:
Copy the codeThe code is as follows:
var fakeArray01 = {a:'a',b:'b',length:2};//No value corresponding to the length subscript
var arr01 = (fakeArray01);
alert(arr01[0]);//undefined
var fakeArray02 = {0:'a',1:'b',length:'num'};//length is not a numerical value
var arr02 = (fakeArray02);
alert(arr02[1]);//undefined
Similarly, fakeArray01 and fakeArray02 are converted into real arrays, but the values in the array are undefined
View V8 Engine The source code of slice can be simplified to:
Copy the codeThe code is as follows:
function slice(start, end) {
var len = ToUint32(), result = [];
for(var i = start; i < end; i++) {
(this[i]);
}
return result;
}
It can be seen that slice does not need this to be of array type, it only needs to have the length attribute. And the length attribute can not be of type number. When it cannot be converted to a numeric value, ToUnit32() returns 0.
According to the above conclusion, it can be concluded that fakeArray01 is converted into an array with lenth of 2, and its values are initialized as undefined, fakeArray02 is converted into an array with length of 0, and naturally accessing elements with subscript of 1 returns undefined
IE's problem
All the problems can be explained for the standard browser slice implementation, but IE has problems dealing with NodeList. There will be an error if NodeList cannot be converted to a real array in IE. Why is this? Strictly speaking, an abstract class Arraioid is defined inside IE, and both Array and Arguments are inherited from this, so you can use slice. However, the DOM object is connected to JScript through COM, and it fails when slice detection.
Jquery and pseudo-array
Jquery uses a lot of pseudo-arrays inside. It can be said that the entire Jquery object is built on the basis of a pseudo-array, so let's take a look at some practical applications of Jquery:
Copy the 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." type="text/javascript"></script>
<script>
$(document).ready(function(){
var body = $("body");
alert((0).tagName);
});
</script>
</head>
<body>
<div ></div>
</body>
</html>
The simplest program, okay, let's take a look at its internal implementation principle:
Copy the codeThe code is as follows:
= = {
init: function( selector, context ) {
var match, elem, ret, doc;
// Handle $(""), $(null), or $(undefined)
if ( !selector ) {
return this;
}
// Handle $(DOMElement)
if ( ) {
= this[0] = selector;
= 1;
return this;
}
// The body element only exists once, optimize finding it
if ( selector === "body" && !context ) {
= document;
this[0] = ;
= "body";
= 1;
return this;
}
//... ...
},
get: function( num ) {
return num == null ?
// Return a 'clean' array
() :
// Return just the object
( num < 0 ? (num)[ 0 ] : this[ num ] );
}
}
Finally, let's explain the execution details of the program. But before that, we have to talk about some things inside Jquery.
Users who have used Jquery should know the $() function, which is the selector representative of Jquery. We may use the $() function to select elements in the page (the specific syntax can be parameterized by Jquery help document). In fact, when we execute the $() function, the program executes the init method listed above. Let’s take a look at the events that occur when calling $(document):
Copy the codeThe code is as follows:
//$(document)
init: function( selector, context ) {
var match, elem, ret, doc;
// Handle $(DOMElement) : handles DOM elements,
if ( ) {
= this[0] = selector; // Assign a selector value to attribute 0, and it is the document object at this time
= 1; //Create a pseudo-array and update the subscript
return this; //Return the Jquery object
}
//... ...
}
$("body") is the same, I won't say more.
We know that all operations in Jquery return Jquery objects, so how do we get the corresponding dom object? Jquery provides us with a get method, which is specially used to obtain DOM objects from jquery objects. Therefore, there is (0). Why is it get(0) instead of get() again, because all operations in Jquery are performed for arrays. Therefore, in the get method, we need to pass a subscript value to get the specific element. Now it's time to look at the specific implementation of the get method:
Copy the codeThe code is as follows:
get: function( num ) {
return num == null ?
//If there is no num, return the DOM array directly
() :
//If the specified num is returned, the element with the specified subscript is returned
//It is another method of jquery. It is actually called to convert a pseudo array into a real array
( num < 0 ? (num)[ 0 ] : this[ num ] );
}
That's all about pseudo-arrays, I think it should be almost done.
Note: If you have the opportunity, a "Beyond Jquery" series may be released in the future, which will specifically analyze the internal execution details of Jquery. However, since Jquery has various evil techniques, it is not very clear that this is a future problem.
refer to:
/blog/2010/05/array-prototype-slice/