《JavaScript框架设计》——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;
}
时间: 2025-01-31 01:44:43

《JavaScript框架设计》——1.3 数组化的相关文章

javascript框架设计之框架分类及主要功能

这篇文章主要介绍了javascript框架设计之框架分类及主要功能的相关资料,需要的朋友可以参考下 从内部架构和理念划分,目前JavaScript框架可以划分为5类. 第一种是以命名空间为导向的类库或框架,如果创建一个数组用new Array(),生成一个对象用new Object(),完全的java风格,因此,我们以某一对象为跟,不断为它添加对象和二级对象属性来组织代码,如金字塔般垒起来,早期代表YUI,EXT(so,不是有活力的公司都还用它们) 第二种是以类工厂为导向的框架.著名的有Prot

javascript框架设计之框架分类及主要功能_javascript技巧

从内部架构和理念划分,目前JavaScript框架可以划分为5类. 第一种是以命名空间为导向的类库或框架,如果创建一个数组用new Array(),生成一个对象用new Object(),完全的java风格,因此,我们以某一对象为跟,不断为它添加对象和二级对象属性来组织代码,如金字塔般垒起来,早期代表YUI,EXT(so,不是有活力的公司都还用它们) 第二种是以类工厂为导向的框架.著名的有Prototype,还有mootools.Base2.Ten,它们基本上除了最基本的命名空间,其它模块都是一

javascript框架设计读书笔记之种子模块_javascript技巧

1.命名空间: js里面的命名空间就是使用对象的属性来扩展的.比如,用户定义一个A对象,A对象下面有B属性和C属性,同时B属性和C属性又是对象.因此A={B:{},C:{}},这时用户就可以在B对象和C对象中定义一样的方法,属性了.因此B和C就属于不同的命名空间.我们调用B,C对象里面的方法,就可以通过A.B.like(),A.C.like()调用了.当然A属于window对象中的属性. 但是有一种情况,比如:boke.jsp页面引入了jquery.js以及prototype.js(他们都会在w

javascript框架设计读书笔记之模块加载系统_javascript技巧

模块加载,其实就是把js分成很多个模块,便于开发和维护.因此加载很多js模块的时候,需要动态的加载,以便提高用户体验. 在介绍模块加载库之前,先介绍一个方法. 动态加载js方法: 复制代码 代码如下: function loadJs(url , callback){ var node = document.createElement("script");       node[window.addEventListener ? "onload":"onre

javascript框架设计之类工厂

 这篇文章主要介绍了javascript框架设计之类工厂的相关资料,非常浅显易懂,有需要的小伙伴可以查看下.     类与继承在javascript的出现,说明javascript已经达到大规模开发的门槛了,在之前是ECMAScript4,就试图引入类,模块等东西,但由于过分引入太多的特性,搞得javascript乌烟瘴气,导致被否决.不过只是把类延时到ES6.到目前为止,javascript还没有正真意义上的类.不过我们可以模拟类,曾近一段时间,类工厂是框架的标配,本章会介绍各种类实现,方便大

javascript框架设计之类工厂_javascript技巧

类与继承在javascript的出现,说明javascript已经达到大规模开发的门槛了,在之前是ECMAScript4,就试图引入类,模块等东西,但由于过分引入太多的特性,搞得javascript乌烟瘴气,导致被否决.不过只是把类延时到ES6.到目前为止,javascript还没有正真意义上的类.不过我们可以模拟类,曾近一段时间,类工厂是框架的标配,本章会介绍各种类实现,方便大家在自己的框架中或选择时自己喜欢的那一类风格. 1.javascript对类的支持 在其它语言中 ,类的实例都要通过构

《JavaScript框架设计》——第 1 章 种子模块 1.1命名空间

第 1 章 种子模块 种子模块也叫核心模块,是框架的最先执行的部分.即便像jQuery那样的单文件函数库,它的内部也分许多模块,必然有一些模块冲在前面立即执行,有一些模块只有用到才执行,也有一些模块可有可无,存在感比较弱,只在特定浏览器下才运行. 种子模块就是其中的急先锋,它里面的方法不一定要求个个神通广大,设计优良,但一定极具扩展性,常用,稳定.扩展性是指通过它们能将其他模块的方法包进来,让种子像大树一样成长:常用是指绝大多数模块都用到它们,防止做重复工作:稳定是指不能轻易在以后版本就给去掉,

《JavaScript框架设计》——导读

前言 首先说明一下,本书虽是讲解框架设计,但写个框架不是很深奥的事情,重点是建立更为完整的前端知识树.只有自己尝试写个框架,才有机会接触像原型.作用域.事件代理.缓存系统.定时器等深层知识,也才有机会了解applyElement.swapNode.importNode.removeNode.replaceNode.insertAdjacentHTML.createContextualFragment.runtimeStyle等偏门API,也才会知晓像getElementById.getEleme

《JavaScript框架设计》——第 1 章 种子模块1.1 命名空间

第 1 章 种子模块 种子模块也叫核心模块,是框架的最先执行的部分.即便像jQuery那样的单文件函数库,它的内部也分许多模块,必然有一些模块冲在前面立即执行,有一些模块只有用到才执行,也有一些模块可有可无,存在感比较弱,只在特定浏览器下才运行. 种子模块就是其中的急先锋,它里面的方法不一定要求个个神通广大,设计优良,但一定极具扩展性,常用,稳定.扩展性是指通过它们能将其他模块的方法包进来,让种子像大树一样成长:常用是指绝大多数模块都用到它们,防止做重复工作:稳定是指不能轻易在以后版本就给去掉,