javascript 类数组对象

参考自: https://github.com/justjavac/12-javascript-quirks/blob/master/cn/8-array-like-objects.md

简单来说: 具有length属性并且可以通过数字下标方式访问属性的对象就是类数组对象, 它不一定具有数组的方法( 你可以用 Object.getOwnPropertyNames(Array.prototype) 来看一个对象默认有哪些方法 ).

 

<<>javascript权威指南>> 中判断类数组对象的一个方法:

// 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 (text node type) 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
}

 

哪里会用常到类数组对象:

  1. arguments 就是类数组对象

  2. DOM( 用来操作XML,HTML的API ) 操作的返回值(i.e.  document.getElementsByClassName() ) 通常就是类数组对象

 

怎么创建一个类数组对象? 在这个之前先要了解方法借用.

  方法借用: 每个函数 myfunc 都有一个 call 的属性(也是一个函数), 可以从下面打印出 Function.prototype 的所有属性来看:

console.log(Object.getOwnPropertyNames(Function.prototype));
//["length", "name", "arguments", "caller", "constructor", "bind", "toString", "call", "apply"]

  fun.call(thisArg[, arg1[, arg2[, ...]]])  中有一个thisArg 让你自己选择调用这个myfunc 的对象(this), 这样就能把 myfunc "借" 出去. 那么其他对象如果能用这个方法, 就可以借来用. ----- 这样 myfyunc 就变成了一个通用方法.   

  所以你可以这样使用: 

var o = {
    name : "roger",
    age : 21
}
function f(){
    for(var p in this){
        console.log(o[p]);
    }
}
f.call(o);

  f 是一个普通的方法, 但是可以把它当成对象 o 的方法来使用. 当然 如果 f 是其他某个对象的方法也没问题( 如:  Array.prototype.slice() )

  好了, 这样我们就可以从一个对象开始创建类数组对象 --- 只要让它变得有 length 属性 和 可以数字下标访问即可: 

var obj = {}; // 首先创建一个对象
Array.prototype.push.call(obj,'a','b'); // 借用数组的方法往对象里面添加元素

  这样我们就将 obj 变成了一个类数组对象, 输出 obj 可以看到:  Object {0: "a", 1: "b", length: 2} , 添加元素时, 自动创建了数字下标 和 length属性(自动初始化为0 并自动管理).

  但是记住这个obj 仍然是一个对象, 它没有实现数组的其他方法, 使用 Array,isArray(obj) 会得到 false , 很多情况下这样够我们用了!

  不过, 如果你觉得数组的其他操作也是需要的, 那么, 你可以进一步将 obj 转化为数组:  obj = Array.prototype.slice.call(obj); 这样, Array,isArray(obj) 就得到 true 了!

 

posted @ 2015-12-29 15:22  roger9567  阅读(279)  评论(0编辑  收藏  举报