JavaScript: The Definitive Guide, Sixth Editio javaScript权威指南(第6版) pdf 文字版-文字版, javascript电子书, 和javascript 有关的电子书:

7.11 Array-Like Objects

This test of the class attribute is, in fact, exactly what the ECMAScript 5 Array.isArray()function does. The technique for obtaining the class of an object using Object.prototype.toString()is explained in §6.8.2 and demonstrated in Example 6-4 .


7.11 Array-Like Objects

As we’ve seen, JavaScript arrays have some special features that other objects do not have:

These are the features that make JavaScript arrays distinct from regular objects. But they are not the essential features that define an array. It is often perfectly reasonable to treat any object with a numeric length property and corresponding non-negative integer properties as a kind of array.

These “array-like” objects actually do occasionally appear in practice, and although you cannot directly invoke array methods on them or expect special behavior from the length property, you can still iterate through them with the same code you’d use for a true array. It turns out that many array algorithms work just as well with array-like objects as they do with real arrays. This is especially true if your algorithms treat the array as read-only or if they at least leave the array length unchanged.

The following code takes a regular object, adds properties to make it an array-like object, and then iterates through the “elements” of the resulting pseudo-array:

var a = {}; // Start with a regular empty object

// Add properties to make it "array-like" var i = 0; while(i < 10) {

a[i] = i * i;

i++; } a.length = i;

// Now iterate through it as if it were a real array var total = 0; for(var j = 0; j < a.length; j++)

total += a[j];

The Arguments object that’s described in §8.3.2 is an array-like object. In client-side JavaScript, a number of DOM methods, such as document.getElementsByTagName(), return array-like objects. Here’s a function you might use to test for objects that work like arrays:

// Determine if o is an array-like object. // Strings and functions have numeric length properties, but are // excluded by the typeof test. In client-side JavaScript, DOM text // nodes have a numeric length property, and may need to be excluded // with an additional o.nodeType != 3 test. function isArrayLike(o) {

if (o && // o is not null, undefined, etc. typeof o === "object" && // o is an object isFinite(o.length) && // o.length is a finite number o.length >= 0 && // o.length is non-negative o.length===Math.floor(o.length) && // o.length is an integer o.length < 4294967296) // o.length < 2^32 return true; // Then o is array-like

else return false; // Otherwise it is not }

We’ll see in §7.12 that ECMAScript 5 strings behave like arrays (and that some browsers made strings indexable before ECMAScript 5). Nevertheless, tests like the one above for array-like objects typically return false for strings—they are usually best handled as strings, not as arrays.

The JavaScript array methods are purposely defined to be generic, so that they work correctly when applied to array-like objects in addition to true arrays. In ECMAScript 5, all array methods are generic. In ECMAScript 3, all methods except toString() and toLocaleString() are generic. (The concat() method is an exception: although it can be invoked on an array-like object, it does not property expand that object into the returned array.) Since array-like objects do not inherit from

7.11 Array-Like Objects | 159

Array.prototype, you cannot invoke array methods on them directly. You can invoke them indirectly using the Function.call method, however:

var a = {"0":"a", "1":"b", "2":"c", length:3}; // An array-like object Array.prototype.join.call(a, "+") // => "a+b+c" Array.prototype.slice.call(a, 0) // => ["a","b","c"]: true array copy Array.prototype.map.call(a, function(x) {

return x.toUpperCase(); }) // => ["A","B","C"]:

We’ve seen this call() technique before in the isArray() method of §7.10 . The call() method of Function objects is covered in more detail in §8.7.3 .

The ECMAScript 5 array methods were introduced in Firefox 1.5. Because they were written generically, Firefox also introduced versions of these methods as functions defined directly on the Array constructor. With these versions of the methods defined, the examples above can be rewritten like this:

var a = {"0":"a", "1":"b", "2":"c", length:3}; // An array-like object Array.join(a, "+") Array.slice(a, 0) Array.map(a, function(x) { return x.toUpperCase(); })

These static function versions of the array methods are quite useful when working with array-like objects, but since they are nonstandard, you can’t count on them to be defined in all browsers. You can write code like this to ensure that the functions you need exist before you use them:

Array.join = Array.join || function(a,sep) {

return Array.prototype.join.call(a,sep); }; Array.slice = Array.slice || function(a,from,to) {

return Array.prototype.slice.call(a,from,to); }; Array.map = Array.map || function(a, f, thisArg) {

return Array.prototype.map.call(a, f, thisArg);

欢迎转载,转载请注明来自一手册:http://yishouce.com/book/1/27660.html
友情链接It题库(ittiku.com)| 版权归yishouce.com所有| 友链等可联系 admin#yishouce.com|粤ICP备16001685号-1