How does jQuery allow you to use [] on a jQuery object?
Say I had the following markup:
<div></div>
<div></div>
<div></div>
And I use the following to retrieve them:
var divs = $('div');
How is it possible that I am able to retrieve the respective DOM element by using the []
syn开发者_开发问答tax and also be able to call methods on the jQuery object such as .first()
?
var div_one = divs[0];
I'm asking this question because it looks to me that divs
is a jQuery object, not a true JavaScript Array
object.
How does this work?
The numeric indices are just properties of the returned object. It's similar to doing this:
var obj = {};
obj[0] = 'foo';
alert(obj[0]);
Arrays and pseudo-array objects are almost identical - the only difference is that the length
property of a true array is automatically managed by the JavaScript engine.
You can do this with any object. It doesn't really have anything to do with it being an "Array-like" object.
var myObj = {};
myObj[0] = 'some value';
alert( myObj[0] );
Here's an example of creating an Array-like object:
Example: http://jsfiddle.net/8rgRM/
// create constructor
function MyObj(){}
// extend it with an Array method
MyObj.prototype.push = Array.prototype.push;
// create an instance
var inst = new MyObj;
// use the push method
inst.push( 'some value' );
// the instance automatically has a length property that was updated
alert( inst.length );
It may be tempting to thing that the length property will behave just as it will in an actual Array, but it doesn't.
For example, with an Array you can do length = 0
to clear the content of the Array, but it won't work in an object like the one above.
In jQuery's source, here is where Array.prototype.push is referenced, and here is where it is extended into the jQuery prototype.
This would clear things up a bit. Try it and play with it.
//used to produce pure classical inheritance
function clone(obj){
function F(){};
F.prototype=obj;
return new F();
}
// Constructor function, used to instantiate a new object of myDivQuery Class
myDivQuery = function (){
var div_list = document.getElementsByTagName('div');
for (var i=0; i < div_list.length; i++){
this[i] = div_list[i];
}
this.length = div_list.length;
};
//myDivQuery inherits from Array class
myDivQuery.prototype = clone( new Array );
//add new methods to myDivQuery class, which is not added to the orginal Array class
myDivQuery.prototype.first = function (){
return this[0];
}
myDivQuery.prototype.last = function (){
return this[this.length - 1]
}
divs = new myDivQuery();
divs[0]; // first div on the page;
divs[1]; // the second div on the page ....
divs instanceof Array; //true
divs instanceof myDivQuery; //true
divs.first() === divs[0]; //true
divs.last(); //last div on page
Array.prototype.first; //undefined
divs.slice(1); //but still can use array methods
divs.reverse(); //another array method
this is how you sort of create a pseudo array, one huge remark is Arrays in javascript can't be sub classed, i.e. cannot create a sub array with the same array features, the main reason for that is the behavior of the length property in an array, which is hidden from the JS programmer, but there is many hacks and work-arounds for doing that, to learn more read this brilliant article by kangax. http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/
In JavaScript you can access properties of objects using the same syntax used for array-index notation:
var o = {'foo':'bar'},
fooVar = 'bar';
//these all alert 'bar'
alert(o.foo);
alert(o['foo']);
alert(o[fooVar]);
However, you can only use the dot notation for valid names. o[0]
works, but o.0
does not.
jQuery returns a jQuery.init
object that contains a number of properties (i.e. length
), as well as a map of the dom elements
or other raw javascript objects matched by the selector, listed from 0
to n
.
The result of a selector ($("div")
in the start post) returns a result with the type Jquery
To quote from the jquery page:
The jQuery object itself behaves much like an array; it has a length property and the elements in the object can be accessed by their numeric indices [0] to [length-1]. Note that a jQuery object is not actually a Javascript Array object, so it does not have all the methods of a true Array object such as join().
精彩评论