javascript 类数组

在线的《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:“类数组对象”

    原文作者:52lidan
    原文地址: https://segmentfault.com/a/1190000000415572
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞