《JavaScript框架设计》——1.3 数组化

简介: 浏览器下存在许多类数组对象,如function内的arguments,通过document.forms、form. elements、doucment.links、select.options、document.getElementsByName、document.getElementsBy TagName、childNodes、children等方式获取的节点集合(HTMLCollection、NodeList),或依照某些特殊写法的自定义对象。

本节书摘来自异步社区《JavaScript框架设计》一书中的第1章,第1.3节,作者:司徒正美著,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.3 数组化

浏览器下存在许多类数组对象,如function内的arguments,通过document.forms、form. elements、doucment.links、select.options、document.getElementsByName、document.getElementsBy TagName、childNodes、children等方式获取的节点集合(HTMLCollection、NodeList),或依照某些特殊写法的自定义对象。

var arrayLike = {
    0: "a",
    1: "1",
    2: "2",
    length: 3
}

类数组对象是一个很好的存储结构,不过功能太弱了,为了享受纯数组的那些便捷方法,我们在处理它们前都会做一下转换。

通常来说,只要[].slice.call就能转换了,但旧版本IE下的HTMLCollection、NodeList不是Object的子类,采用如上方法将导致 IE 执行异常。我们看一下各大库怎么处理的。

//jQuery的makeArray
var makeArray = function(array) {
    var ret = [];
    if (array != null) {
        var i = array.length;
        // The window, strings (and functions) also have 'length'
        if (i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval)
            ret[0] = array;
        else
            while (i)
                ret[--i] = array[i];
    }
    return ret;
}

jQuery对象是用来储存与处理dom元素的,它主要依赖于setArray方法来设置和维护长度与索引,而setArray的参数要求是一个数组,因此makeArray的地位非常重要。这方法保证就算没有参数也要返回一个空数组。

Prototype.js的$A方法:

function $A(iterable) {
    if (!iterable)
        return [];
    if (iterable.toArray)
        return iterable.toArray();
    var length = iterable.length || 0, results = new Array(length);
    while (length--)
        results[length] = iterable[length];
    return results;
};

mootools的$A方法:

function $A(iterable) {
    if (iterable.item) {
        var l = iterable.length, array = new Array(l);
        while (l--)
            array[l] = iterable[l];
        return array;
    }
    return Array.prototype.slice.call(iterable);
};

Ext的toArray方法:

var toArray = function() {
    returnisIE ?
            function(a, i, j, res) {
                res = [];
                Ext.each(a, function(v) {
                    res.push(v);
                });
                return res.slice(i || 0, j || res.length);
            } :
            function(a, i, j) {
                return Array.prototype.slice.call(a, i || 0, j || a.length);
            }
}()

Ext的设计比较巧妙,功能也比较强大。它一开始就自动执行自身,以后就不用判定浏览器了。它还有两个可选参数,对生成的纯数组进行操作。

dojo的_toArray和Ext一样,后面两个参数是可选的,只不过第二个是偏移量,最后一个是已有的数组,用于把新生的新组元素合并过去。

(function() {
    var efficient = function(obj, offset, startWith) {
        return (startWith || []).concat(Array.prototype.slice.call(obj, offset || 0));
    };
    var slow = function(obj, offset, startWith) {
        var arr = startWith || [];
        for (var x = offset || 0; x > obj.length; x++) {
            arr.push(obj[x]);
        }
        returnarr;
    };
    dojo._toArray =
            dojo.isIE ? function(obj) {
        return ((obj.item) ? slow : efficient).apply(this, arguments);
    } :
            efficient;
})();

最后是mass的实现,与dojo一样,一开始就进行区分,W3C方直接[].slice.call,IE自己手动实现一个slice方法。

$.slice = window.dispatchEvent ? function(nodes, start, end) {
    return [].slice.call(nodes, start, end);
} : function(nodes, start, end) {
    var ret = [],
            n = nodes.length;
    if (end === void 0 || typeof end === "number" && isFinite(end)) {
        start = parseInt(start, 10) || 0;
        end = end == void 0 ? n : parseInt(end, 10);
        if (start < 0) {
            start += n;
        }
        if (end > n) {
            end = n;
        }
        if (end < 0) {
            end += n;
        }
        for (var i = start; i < end; ++i) {
            ret[i - start] = nodes[i];
        }
    }
    return ret;
}
相关文章
|
11天前
|
存储 JavaScript 索引
js开发:请解释什么是ES6的Map和Set,以及它们与普通对象和数组的区别。
ES6引入了Map和Set数据结构。Map的键可以是任意类型且有序,与对象的字符串或符号键不同;Set存储唯一值,无重复。两者皆可迭代,支持for...of循环。Map有get、set、has、delete等方法,Set有add、delete、has方法。示例展示了Map和Set的基本操作。
29 3
|
11天前
|
存储 JavaScript 索引
JS中数组的相关方法介绍
JS中数组的相关方法介绍
|
11天前
|
JavaScript Java
JS有趣的灵魂 清空数组
JS有趣的灵魂 清空数组
|
6天前
|
前端开发 JavaScript
前端 js 经典:数组常用方法总结
前端 js 经典:数组常用方法总结
15 0
|
11天前
|
JavaScript
通过使用online表单的获取使用,了解vue.js数组的常用操作
通过使用online表单的获取使用,了解vue.js数组的常用操作
13 0
|
11天前
|
存储 JavaScript 前端开发
深入了解JavaScript中的indexOf()方法:实现数组元素的搜索和索引获取
深入了解JavaScript中的indexOf()方法:实现数组元素的搜索和索引获取
11 0
|
11天前
|
JavaScript 前端开发
js关于数组的方法
js关于数组的方法
13 0
|
11天前
|
JavaScript 前端开发
js怎么清空数组?
js怎么清空数组?
14 0
|
11天前
|
存储 JavaScript 前端开发
js处理数组的方法
js处理数组的方法
15 2
|
11天前
|
JavaScript 前端开发 索引
JavaScript 数组的索引方法数组转换为字符串方法
JavaScript 数组的索引方法数组转换为字符串方法