Javascript框架设计之对象数组化

类数组对象是一个很好的存储结构,但是功能太弱了,为了享受纯数组的哪些便捷的方法,使用前可以做下转换,通常可以使用$.slice.call()方法做转换,但是旧版本的IE下的HTMLCollection、NodeList不是Object的子类,如果采用[].slice.call()方法可能会导致异常,下面是各大库是怎么处理的:

1、jQuery的makeArray

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../../common/jquery-1.9.1.min.js"></script>
</head>
<body>
    <script>
        //一般将一个对象转换成数组需要用[].slice.call()方法来转换,但是在旧版本的IE中HTMLCollection、NodeList不是Object的子类,是com对象
        //所以无法使用[].slice.call()方法来把传入的对象数组化,下面是jQuery兼容IE旧版本的对象数组化方法

        //该方法有以下保证
        /*
        1、不管是否传入参数,始终返回一个数组,如果不传参,则返回一个空数组
        2、对传入的参数(不包含length属性、是字符串、是jQuery方法的、是array的setInterval的)将他们的引用存入数组的第一项
        3、如果传入的参数符合数组化的要求,则进行数组化
         */

        //注意:传入的集合必须是具有length属性,然后集合的键值必须是数字,也就是具有数组结构的集合,才能被转换
        var makeArray=function(array)
        {
            var ret=[];
            if(array!=null)
            {
                var l=array.length;
                if(l==null || typeof array==="string" ||jQuery.isFunction(array) || array.setInterval)
                {
                    ret[0]=array;
                }
                else
                {
                    while (l)
                    ret[--l]=array[l];
                }
            }
            return ret;
        }
        alert(makeArray({length:3,0:"a",1:"b",2:"c"})[1]);
    </script>
</body>
</html>

2、dojo的对象数组化方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script>
        /*
        dojo的对象数组化方法和Ext一样,都是在一开始判断浏览器类型,他的后面也有两个参数,用于操作转化后的数组
        但是dojo后面的两个参数,不是要截取数组的开始索引和结束索引
        dojo的第一个参数是要转换成数组的对象,第二个是偏移量,第三个是已有的数组,返回值是已有的数组和转换后,并截取过的合并数组
         */
        var zc={};
        isIE=true;
        (function(){
            var efficient=function (obj,offest,startWith) {
                return (startWith||[]).concat([].slice.call(obj,offest || 0));
            }
            var slow=function (obj,offest,startWith) {
                 var arr=startWith || [];
                //偏移量不支持负数
                 for(var i=offest || 0;i<obj.length;i++) {
                     arr.push(obj[i]);
                 }
                return arr;
            }
            zc.toArray=isIE?function (obj) {
                return slow.apply(this,arguments);
            }:efficient;
        })();
        alert(zc.toArray({length:3,0:"a",1:"b",2:"c"},0,[1,2,3]));
    </script>
</body>
</html>

3、Ext的对象数组化方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script>
        /*
        Ext设计的比较巧妙,在框架一加载的同时,就判断浏览器的的类型,然后存到变量中,后面就不需要判断浏览了,
        然后根据浏览器的是不是IE来选择toArray到底引用那个方法体,如果是IE浏览器,则吊用自定义的对象数组化方法,
        如果不是则调用[].slice.call(),并通过slice方法,通过i,j参数对字符串进行截取操作
        */
        /*
        该方法有以下保证
        1、如果在IE浏览器下执行,则则调用自定义的对象数组化方法
        2、如果不再IE下,吊用[].slice.call()来进行对象数组化
        3、可以提供两个参数(start,end),用于截取指定长度的转换后的对象数组
         */
        var toArray=function () {
            var returnisIE;//判断浏览器是否是IE
            return returnisIE?function(a,i,j){
                var length=a.length || 0,result=new Array(length);
                while (length--)
                result[length]=a[length];
                return result.slice(i || 0,j|| a.length);
            }:function(a,i,j){
                return Array.prototype.slice.call(a,i || 0,j || a.length);
            };
        }();
        var res=toArray({length:2,0:"a",1:"2"},1);
        alert(res)
    </script>
</body>
</html>

4、mootools

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /*
    mootools的对象数组化方法
     */
    /*
    该方法有以下保证
    1、当用户传入的是HTMLCollection集合是,因为老版IE的HTML节点对象是COM对象,不是Js对象的子类,所以无法使用[].slice.call()方法
    使用自定义的对象数组化方法
    2、如果传入的对象不是上面的那种情况,那么吊用[].slice.call()方法来进行对象数组化
     */
    function $A(array)
    {
        if(array.item)
        {
            var length=array.length || 0,result=new Array(length);
            while (length--)
            result[length]=array[length];
            return result;
        }
        return Array.prototype.slice.call(array);
    }
    var res=$A({length:2,0:1,1:2});//输出:1,2
    alert(res)
</script>
</body>
</html>

5、Prototype

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /*
    Prototype的对象转换成数组的方法
     */

    /*
    该方法有以下保证
    1、如果不传入参数,返回空数组
    2、如果当前浏览器支持toArray()方法,那么调用该对象的toArray()方法
    3、如果上面两种条件都不满足,那么拿到当前对象的length属性(如果没有给0),然后new一个具有length长度的数组,并进行赋值
     */

    //注意:要转换成数组的对象的length不能大于实际元素的长度,也不能小于实际元素的长度
    function $A(array){
        if(!array)return [];
        if(array.toArray)return array.toArray();
        var length=array.length || 0,results=new Array(length);
        while (length--)
        results[length]=array[length];
        return results;
    }
    var result=$A({length:3,0:1,1:2,2:3});
    alert(result);
</script>
</body>
</html>

6、mass

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
/*
下面是mass的对象数组化方法
 */
/*
该方法有以下保证:
1、一开始就对浏览器进行区分
2、如果是IE则调用自定义对戏那个数组化方法,如果不是,则使用[].slice.call
3、提供start和end参数,方便对(传入对象数组化之后的数组)进行截取
4、保证start和end参数的输入不会影响输出结果
 */
isIE=true;
var toArray=window.isIE?function(nodes,start,end)
{
    var ret=[],length=nodes.length;
    if(end===void 0 || typeof  end==="number" && isFinite(end))
    {
        start=parseInt(start,10) || 0;
        end=end==void 0?length:parseInt(end,10);
        if(start<0)
            start+=length;
        if(end>length)
            end=length;
        if(end<0)
            end+=length;
        for(var i=start;i<end;i++)
        {
            ret[i-start]=nodes[i];
        }
    }
    return ret;
}:function (nodes,start,end)
{
    return Array.prototype.slice.call(nodes,start,end);
};
var res=toArray({length:3,0:1,1:"a",2:"b"},0,-1);//输出:1,a
    alert(res);
</script>
</body>
</html>
时间: 2024-12-25 11:40:09

Javascript框架设计之对象数组化的相关文章

js 框架设计1.3数组化

这一节从作者哪里学来了[].slice.call([],0,1);这个方法第一个参数可是是字符串可以是数组或其他,第2个是数组截取位置的开始位置,第3个是终止位置. 作者说这个方法不兼容旧版本ie的,HTMLCollection.NodeList不是Object的子类 所以在最后写了一个mass framework里面的方法,具体的代码如下. 当然在我们日常用的jq当中,我可以调用makeArray()的方法,就算没有数组也要返回空数组. 插入jq的 makeArray()方法先 var mak

JS读书笔记:《JavaScript框架设计》——第12章 异步处理

一.何为异步   执行任务的过程可以被分为发起和执行两个部分. 同步执行模式:任务发起后必须等待直到任务执行完成并返回结果后,才会执行下一个任务. 异步执行模式:任务发起后不等待任务执行完成,而是马上执行下一个任务,当任务执行完成时则会收到通知. 面对IO操作频繁的场景,异步执行模式可在同等的硬件资源条件下提供更大的并发处理能力,也就是更大的吞吐量. 但由于异步执行模式打破人们固有的思维方式,并且任务的发起和任务的执行是分离的,从而提高编程的复杂度. 多线程.多进程均可实现异步模式. 二.从回调

JavaScript框架设计 pdf jQuery技术内幕 pdf

jQuery技术内幕  深入解析jQuery架构设计与实现原理 PDF电子书带目录  高清版 JavaScript框架设计  现代魔法指南 PDF电子书带目录 高清版 网络上的都是预览版,这是自制的,如有需要请联系qq:1067728292 10元一本,已然是最低价不讲价.

JavaScript 框架设计 司徒正美 编著

第1章 种子模块 1.1 命名空间 1.2 对象扩展 1.3 数组化 1.4 类型的判定 1.5 主流框架引入的机制--domReady 1.6 无冲突处理 第2章 模块加载系统 2.1 AMD规范 2.2 加载器所在路径的探知 2.3 require方法 2.4 define方法 第3章 语言模块 3.1 字符串的扩展与修复 3.2 数组的扩展与修复 3.3 数值的扩展与修复 3.4 函数的扩展与修复 3.5 日期的扩展与修复 第4章 浏览器嗅探与特征侦测 4.1 判定浏览器 4.2 事件的支

《JavaScript框架设计》

第一章  种子模块 种子模块也是核心模块,框架最先执行的部分,模块分为立即执行.调用才执行,可有可无. 种子模块包括:对象扩展,数组化,类型判定,事件的绑定和卸载,无冲突处理,模块加载和domReady 一.命名空间 各大库的实现,一开始都定义一个全局变量作为命名空间,然后对他进行扩展 1 if (typeof(Ten) === "undefined") { 2 Ten = {}; 3 Ten.Function = {}; 4 Ten.Array = {}; 5 Ten.Class =

JavaScript权威设计--Window对象之Iframe(简要学习笔记十四)

1.Window对象属性的文档元素(id) 如果在HTML文档中用id属性来为元素命名,并且如果Window对象没有此名字的属性,Window对象会赋予一个属性,它的名字是id属性的值,而他们的值指向表示文档元素的HTMLElement对象. Window对象是以全局对象的形式存在于作用域链的最上层,这就意味着HTML文档中使用的id属性会成为可以被脚本访问的全局变量. 如: <button id="but"/> 就可以通过全局变量but来引用此元素. 2.多窗体窗口(if

JavaScript权威设计--Window对象(简要学习笔记十三)

1.Window对象是所有客户端JavaScript特性和API的主要接入点. Window对象中的一个重要属性是document,它引用Document对象. JavaScript程序可以通过Document对象和它包含的Element对象遍历和管理文档. 2.URL中的JavaScript 在URL后面跟一个JavaScript:协议限定符.里面的代码会作为JavaScript代码进行运行,需用分号分割. 如: <a href="javascript:alert('OK!')"

JavaScript框架设计---大神的框架研究笔记

原本是想买一本教如何去写一个js框架的书的,这本书完全是正美大神的框架源码阅读笔记,看的我这个非专业前端很是乏力,经常几个框架间跳来跳去,一下子就跟丢了,只能默默为自己的前端功力掩面.后来就本着了解和欣赏的态度去看,这样就好多了.  还是谈谈我看这本书的收获吧  1.大神们写代码真是惜墨如金.  2.底层API原来还有这么多,JavaScript高级编程,JavaScript权威指南都没讲完.  3.兼容性神马的IE这么多,也不单只有IE,FF,chrome都有兼容性问题.Jquery这些前端框

JavaScript框架设计 司徒正美 编著

1.框架与库 下面稍微说一下框架与库的区别. 库是解决某个问题而拼凑出来的一大堆函数与类的集合.例如,盖一个房子,需要有测量 的方法.砌砖的方法.安装门窗的方法等.每个方法之间都没什么关联.至于怎么盖房子都由 自己决定. 框架则是一个半成品的应用,直接给出一个骨架,还例如盖房子,照着图纸砌砖.铺地板 与涂漆就行了.在后端 Java 的三大框架中,程序员基本上就是与 XML 打交道,用配置就可以 处理 80%的编程问题. 从上面描述来看,框架带来的便利性无疑比库好许多.但前端 JavaScript