logo
Published on

如何遍历或枚举 JavaScript 对象?

Authors
  • Name
    Twitter

在JavaScript中,遍历对象并非一件容易的事。虽然有多种方法可以实现,但每种方法都有其优缺点。本文将介绍几种常见的遍历方法,并分享一种独特的方式,使对象可以像 Map 一样被迭代。

使用 Object.keys()for...of

大多数开发者会使用 Object.keys()for...of 结合来遍历对象的键和值:

var map = { well: 'hello', there: '!' };
for (let key of Object.keys(map))
    console.log(key + ':' + map[key]);

由于对象不是一个迭代器,我们不能直接对它们使用 for...of,因此必须先获取对象的键,然后遍历这些键。

自定义迭代器使对象可被遍历

为了简化上述操作,我们可以自定义一个迭代器,使普通对象也能通过 for...of 进行遍历。下面是一个示例:

Object.prototype[Symbol.iterator] = function() {
    var keys = Object.keys(this)[Symbol.iterator]();
    var obj = this;
    var output;
    return {
        next: function() {
            if (!(output = keys.next()).done)
                output.value = [output.value, obj[output.value]];
            return output;
        }
    };
};

现在,我们可以像迭代 Map 一样迭代对象:

var ordinaryObject = { well: 'hello', there: '!' };
for (let [key, value] of ordinaryObject)
    console.log(key + ':' + value);

不想修改 prototype?实现独立函数

如果不想修改 Objectprototype,可以实现一个独立函数来达到相同的效果:

function getObjIterator(obj) {
    var iterator = {};
    iterator[Symbol.iterator] = function() {
        var keys = Object.keys(obj)[Symbol.iterator]();
        var output;
        return {
            next: function() {
                if (!(output = keys.next()).done)
                    output.value = [output.value, obj[output.value]];
                return output;
            }
        };
    };
    return iterator;
}

// 使用示例
var realMap = new Map(getObjIterator({ well: 'hello', there: '!' }));

for (let pair of getObjIterator({ well: 'hello', there: '!' }))
    console.log(pair[0] + ':' + pair[1]);

通过这种方式,可以避免对所有对象都做全局修改,并且仅针对当前对象实现遍历。

总结

JavaScript 提供了多种遍历对象的方法,选择哪种方法取决于具体需求。如果需要简洁且高效的代码,可以使用 Object.keys()for...of 结合的方法。如果希望对象直接具有迭代能力,可以自定义迭代器。当然,也可以采用独立函数的方式来实现特定对象的迭代。无论是哪种方式,都能帮助开发者更加便捷地操作 JavaScript 对象。

欢迎使用这种方式迎接未来的 JavaScript 编程!