遍历对象哈希表

55

我正在尝试使用哈希表来选择存储在数组/对象中的特定对象。然而,我在遍历对象时遇到了问题。

var pins= {};
pins[6] = '6';
pins[7] = '7';
pins[8] = '8';

$('#result3').append('<div>Size: ' + Object.size(pins) + '</div>');
for(var i = 0; i < Object.size(pins); i++) {
    $('#result3').append('<div>' + pins[i] + '</div>');
}

JSFiddle: http://jsfiddle.net/7TrSU/

在使用对象 pin 存储数据的 TEST 3 中,当遍历对象 pin 时,我得到了 undefined。如何正确地遍历 pin

编辑:

如果我将 pin[6] 更改为一个对象,并想要遍历它们所有的 id 属性,会发生什么?以下是我实际正在执行的代码片段...

for(var i = 0; i < json.length; i++) {
    markerId = json[i].listing_id

    // Place markers on map
    var latLng = new google.maps.LatLng(json[i].lat, json[i].lng);
    var marker = new google.maps.Marker({
                listing_id: markerId,
                position: latLng,
                icon: base_url + 'images/template/markers/listing.png',
    });

    markers[markerId] = marker;
}

for(var marker in markers) {
    console.log('marker ID: ' + marker.listing_id);
    mc.addMarker(marker);
}

上面的console.log返回undefined,如果我改为console.log(marker),那么将会返回marker.listing_id的值。抱歉我有点混淆了!

我已经成功使用$.each(markers, function(i, marker){});,但是为什么上面的for..in不起作用呢?


2
你正在在索引6、7和8处添加成员,但是迭代范围是从0到2。更好的策略是从0length-1进行迭代,并在尝试使用成员之前测试其是否存在。 - RobG
你正在混淆数组(arrays)和对象(objects)。 - c69
@c69 - 数组是对象,;-) OP的问题在于尝试访问不存在的属性。 - RobG
@RobG 是的,这就是为什么我点赞了你的评论)) 但他正试图访问不存在的属性,正是因为他不理解自己在做什么。 - c69
如果我不只是使用 pin[6] = '6',而是将 pin[6] 赋值为一个对象,并且我想循环遍历它们所有的属性 id,会发生什么?已更新原帖。 - Nyxynyx
6个回答

112
var hash = {}
hash[key] = value

Object.keys(hash).forEach(function (key) { 
    var value = hash[key]
    // iteration code
})

2
变量值在使用后被创建。 - Yster

52
不要使用for(i=0; i<size; i++)循环,而是使用以下方法之一:
  1. 使用Object.keys(pins) 获取属性列表并进行循环;或者
  2. 使用 for ( key_name in pins)结合Object.hasOwnProperty(排除继承属性)循环遍历属性。
你的第三个测试用例问题在于它读取了键0、1和2的值(而不是6、7、8)。

7

由于您正在使用jQuery:

jQuery.each(pins, function (name, value) {
    $('#result3').append('<div>' + name + "=" + value + '</div>');
});

我使用了你的方法,它按照我想要的方式工作,但我不明白为什么使用 for..in 不起作用... 更新原帖... - Nyxynyx
因为您使用 for..in 进行计数,而不是查找它们的名称。一旦您发现有三个项目,您看到了名称为0、1和2的项目,但这些项目被称为6、7和8。 - Quentin

5

试试这个:

for (var pin in pins) {
    $('#result3').append('<div>' + pin + '</div>');
}

Example fiddle


1
for ... in 循环是次优的 - Raynos
3
不,它们不是。然而,缺少hasOwnProperty是关键。 - c69
1
@c69 for ... inд»Қ然дёҚеӨҹдјҳеҢ–пјҢеӣ дёәе®ғзҡ„жҖ§иғҪжҜ”Object.keysе·®гҖӮhasOwnPropertyжҳҜдёҖдёӘжҳӮиҙөзҡ„и°ғз”ЁгҖӮ - Raynos

5
function iterate(obj){
    var keys = Object.keys(obj);
    for(i in keys){
        doSomething(obj[keys[i]].id);
    }
}

这个函数遍历任何对象中所有字段的id。

-1

pin 以 6 到 8 开始,但 for 循环从 0 到 3(对象的长度)循环。你需要从 6 循环到 6 + 对象的大小。像这样:

for(var i = 6, len = 6 + Object.size(pins); i < len; i++) {
  $('#result3').append('<div>' + pins[i] + '</div>');
}

或者类似这样,这就是我喜欢的:

for( var i = 5; pin = pins[++i]; ) {
  $('#result3').append('<div>' + pin + '</div>');
}

在尝试使用成员之前,最好添加if (pin.hasOwnProperty(i)) …来清除不存在的成员。 - RobG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接