遍历对象

一直以来,遍历对象是个挺麻烦的事,特别是遇到后端那不规范不规则的数据返回的时候,分分钟想掐死……
算了,我F……佛慈悲,自己动手,丰衣足食。

言归正传,和遍历数组不同,object是没有固定下标和顺序可言的,只能通过key值查找,而key值没有一个很完美的方式查找,for in那些总是伴随着兼容问题,新的keys方法也同样如此,那么要很好遍历对象,首先要解决这个问题。

keys的api在ie8等不支持环境会报错,写个hack就好了,具体方法不讨论,可以参考 @di8yuansu 的【关于IE8不支持Object.keys()的处理】

说下思路,不打算在Object原型中拓展,怕冲突,另写个函数就好了。

  • 函数接受对象和要遍历查找的key,参数校验后判断类型(数据类型的知识,可以参考我之前的文章:【JavaScript复制对象和数组】);
  • 接收到的参数为对象或数组,Object.keys或者数组直接遍历;
  • 匹配所有key值,递归遍历查找;
  • 最后数组或者undefined返回查找结果

代码实现如下:

/** 
 * ergod用于遍历对象的值
 * @author mo
 * @param obj 待遍历对象
 * @param key 要遍历的key
 * @return 遍历到的值,返回数组集合;如果为空,则返回undefined
 * @example
 * 
    var obj = {
        a: 2,
        e: {
            h: [
                { g: 9 }
            ]
        },
        f: [
            [
                { g: 7 }
            ]
        ],
        g: {
            g: {
                g: 6
            }
        }
    }
    console.log(ergod(obj, 'g'))

    >> [ 9, 7, { g: { g: 6 } }, { g: 6 }, 6 ]
 *
 */

;(function() {

    var ergod = function(obj, key) {

        // 仅接受两个有效参数
        if (!obj || obj.constructor !== Object || !key || key.constructor !== String) {
            return undefined
        }

        var oi = 0,
            keys = obj.constructor == Object ? Object.keys(obj) : [],
            result = [],
            tmp

        // 数组相关
        if (obj.constructor == Array) {
            keys = []
            for (; oi < obj.length; oi++) {
                keys.push(oi)
            }
            oi = 0
        }

        for (; oi < keys.length; oi++) {

            if (keys[oi] == key) {
                result.push(obj[keys[oi]])
            }

            if (typeof obj[keys[oi]] == 'object') {
                tmp = ergod(obj[keys[oi]], key)
            }

            if (tmp) result = result.concat(tmp)

        }

        return result.length ? result : undefined

    }

    // EXPOSE

    if (typeof define === "function" && define.amd) {
        define(function() { return ergod })
    } else if (typeof module !== "undefined" && module.exports) {
        module.exports = ergod
    } else {
        window.ergod = ergod
    }

    // EXPOSE

})()

你可能感兴趣的:(遍历对象)