zoukankan      html  css  js  c++  java
  • JS框架设计之对象数组化一种子模块

    类数组对象是一个很好的存储结构,但是功能太弱了,为了享受纯数组的哪些便捷的方法,使用前可以做下转换,通常可以使用$.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>
  • 相关阅读:
    弱网测试—Network-Emulator-Toolkit工具
    chmod修改权限
    mysql:on duplicate key update与replace into
    mysql:批量更新
    linux:磁碟与档案系统管理
    linux:指令与档案的搜索
    linux:问题
    linux:档案与目录管理
    linux:档案权限
    linux:习惯
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/6410362.html
Copyright © 2011-2022 走看看