资讯专栏INFORMATION COLUMN

javascript 类数组

int64 / 1972人阅读

摘要:中常见的类数组有对象和方法的返回结果。类数组判断权威指南上给出了代码用来判断一个对象是否属于类数组。此处应当为类数组表现之所以成为类数组,就是因为和数组类似。伪数组转化成数组非伪类对象,直接返回最好针对以前的实现参考的怪癖类数组对象

在线的《javascript权威指南》有对该概念的解释。

那么,什么是javascript 类数组呢?

定义:

拥有length属性,length-0可隐式转换为number类型,并且不大于Math.pow(2,32)(比如:22.33"022"都满足条件)

不具有数组所具有的方法

类数组示例:
var a = {"1":"gg","2":"love","4":"meimei",length:5};
Array.prototype.join.call(a,"+");//"+gg+love++meimei"
非类数组示例:
var c = {"1":2};

没有length属性,所以就不是类数组。

javascript中常见的类数组有arguments对象和DOM方法的返回结果。
比如 document.getElementsByTagName()

类数组判断

《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 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
}

书上给的示例代码判断条件过于严苛,比如以下情形的类数组就无法通过这段代码的校验:

var arrLike1 = { length: 1.2 };
var arrLike2 = { length: -10 };
var arrLike3 = { length: "10" };

当然,除却人为“造作”因素,正常的length应当是正整数。

我们可以对照一下:MDN Array.from 的polyfill , 这个方法中对length的判断可以看一下。

var toInteger = function (value) {
  var number = Number(value);
  if (isNaN(number)) { return 0; }
  if (number === 0 || !isFinite(number)) { return number; }
  return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1; //此处length应当为Math.pow(2, 32) - 1
var toLength = function (value) {
  var len = toInteger(value);
  return Math.min(Math.max(len, 0), maxSafeInteger);
};
类数组表现

之所以成为“类数组”,就是因为和“数组”类似。不能直接使用数组方法,但你可以像使用数组那样,使用类数组。

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"]:
类数组对象转化为数组

有时候处理类数组对象的最好方法是将其转化为数组。
有两种实现方法:

1.数组slice方法借用
Array.prototype.slice.call(arrLike)
2.Array.from
Array.from(arrLike)

然后就可以直接使用数组方法啦。

var a = { "0": 1, "1": 2, "2": 3, length: 3 };
var arr = Array.prototype.slice.call(a); //arr = [ 1, 2, 3  ]

ps: 两个处理方法存在细节差异,比如处理{length: 1}这个对象时,结果就不一样,Array.from处理结果是长度为1并且填充值为undefined,而Array.prototype.slice处理结果则相同于new Array(1)

对于IE9以前的版本(DOM实现基于COM),我们可以使用makeArray来实现。

// 伪数组转化成数组
var makeArray = function(obj) {
    if (!obj || obj.length === 0) {
        return [];
    }
    // 非伪类对象,直接返回最好
    if (!obj.length) {
        return obj;
    }
    // 针对IE8以前 DOM的COM实现
    try {
        return [].slice.call(obj);
    } catch (e) {
        var i = 0,
            j = obj.length,
            res = [];
        for (; i < j; i++) {
            res.push(obj[i]);
        }
        return res;
    }

};
参考:

1.https://www.inkling.com/read/...
2.JavaScript 的怪癖 8:“类数组对象”

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78017.html

相关文章

  • 深入理解JavaScript数组

    摘要:但是,我们可以借用类数组方法不难看出,此时的在调用数组原型方法时,返回值已经转化成数组了。很多时候,深入看看源代码也会让你对这个理解的更透彻。的前端乐园原文链接深入理解类数组 起因 写这篇博客的起因,是我在知乎上回答一个问题时,说自己在学前端时把《JavaScript高级程序设计》看了好几遍。于是在评论区中,出现了如下的对话:showImg(https://segmentfault.c...

    Towers 评论0 收藏0
  • 理解javascript数组

    摘要:也就是说,为一些常规对象增加一些属性可以使其变成类数组对象。实际上,类数组的定义只有一条,具有属性。在中,所有的数组方法都是通用的。 什么是类数组 javascript中一些看起来像却不是数组的对象,叫做类数组。也就是说,为一些常规对象增加一些属性可以使其变成类数组对象。 类数组的特征: 有索引(数字)属性和length属性的对象 不具有数组的方法。间接调用数组的一些方法,比如pus...

    yzzz 评论0 收藏0
  • JavaScript深入之数组对象与arguments

    摘要:在客户端中,一些方法等也返回类数组对象。对象接下来重点讲讲对象。在函数体中,指代该函数的对象。下一篇文章深入之创建对象的多种方式以及优缺点深入系列深入系列目录地址。 JavaScript深入系列第十三篇,讲解类数组对象与对象的相似与差异以及arguments的注意要点 类数组对象 所谓的类数组对象: 拥有一个 length 属性和若干索引属性的对象 举个例子: var array = ...

    AlienZHOU 评论0 收藏0
  • JavaScript 数组对象

    摘要:定义类数组对象的定义可以通过索引访问元素,并且拥有属性没有数组的其他方法,例如,,等。所以当后面的作用对象是一个类数组时,就会把这个类数组对象转换为了一个新的数组。 定义 JavaScript 类数组对象的定义: 可以通过索引访问元素,并且拥有 length 属性; 没有数组的其他方法,例如 push , forEach , indexOf 等。 举例说明 var foo = {...

    haobowd 评论0 收藏0
  • 译文: JavaScript数组对象

    摘要:所以我说的这些类数组对象是什么它们有一些,其中包括是一个很特殊的变量,你再所有函数体内都可以访问到。让类数组对象成为一个数组当然这个标题是不太准确的,假如我们需要将这些类数组对象变成数组一样,我们需要建立一个新的数组。 它看起来像是一个数组,而且它有一个length属性,然而它并不是一个数组。JavaScript有时候是一门很怪异的语言,因为你很难定义一个数组的概念而没有什么例外的。所...

    lbool 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<