【问题标题】:Javascript associative array returns empty/undefined despite being populated inside function尽管在函数内部填充了 Javascript 关联数组,但它返回空/未定义
【发布时间】:2012-11-29 05:57:39
【问题描述】:

我正在开发一个 Javascript 函数,该函数接受一个 XML 文档并创建一个多维(根据需要)关联数组。在函数内部,数组会正确构建,但是在返回 Array 对象时,它会返回一个空数组。

有趣的是,如果我使用 push 方法,并以 {"index": index, "value":value} 的形式推送一个文字数组,而不是使用赋值运算符 (array[index]=value) 它工作得很好

为了测试,我使用以下 XML 节点对象 (Level_1_node):

<Level_1>
    <Level_2>VALUE</Level_2>
</Level_1>

函数如下:

function get_array_from_XML(XML_node){
    var XML_array = new Array();
    var child_node;

    for(var i=0; i<XML_node.childNodes.length; i++){
        child_node = XML_node.childNodes[i];
        if(child_node.childNodes[0]){
            if (child_node.childNodes[0].nodeType == 3){
                XML_array[child_node.nodeName] = child_node.childNodes[0].nodeValue;
            } else {                
                XML_array[child_node.nodeName] = get_array_from_XML(child_node);
            }
        }
    }

    dump(XML_array);  //for my debugging, alerts "LEVEL_2 => VALUE", so everything seems fine

    return XML_array;
}

follow 方法有效,但返回格式不理想:

function get_array_from_XML_using_push(XML_node){
    var XML_array = new Array();
    var child_node;

    for(var i=0; i<XML_node.childNodes.length; i++){
        child_node = XML_node.childNodes[i];
        if(child_node.childNodes[0]){
            if (child_node.childNodes[0].nodeType == 3){
                XML_array.push({
                    "index" : child_node.nodeName,
                    "value" : child_node.childNodes[0].nodeValue
                });
            } else {                
                XML_array.push({
                    "index" : child_node.nodeName,
                    "value" : get_array_from_XML_using_push(child_node)
                });
            }
        }
    }

    dump(XML_array);  //shows the fully populated array

    return XML_array;
}

现在当我运行get_array_from_XML(Level_1_node) 时,它返回一个空数组,但get_array_from_XML_using_push(Level_1_node) 返回

{0 => {"index" => "Level_2", "value" => "VALUE"}}

非常令人沮丧。欢迎任何见解。

【问题讨论】:

  • 你知道javascript没有关联数组吗?他们有数组,他们有对象。如果需要数字索引,请使用数组。如果你想要一个命名索引,使用一个对象并让每个命名索引成为一个属性。
  • 不应在数组 ([]) 中使用非数字“键” - 除了经过适当处理的整数的字符串版本。这适用于对象 ({})。
  • 虽然我听说过“Javascript 不使用关联数组”,但我从未有人深入了解其中的细微差别。这可以解决问题。谢谢。
  • 是的,当您执行list['one'] = 1 时,真正发生的是数组的底层对象插入了名为one 的属性,其值为1。然后可以以list['one']list.one 访问该属性,即它不是数组。但是,您可以拥有一个对象数组,只要索引是一个实际整数并且被分配的对象已正确初始化,即list[1] = { key: value };

标签: javascript return-value associative-array dynamic-arrays


【解决方案1】:

new Array() 更改为new Object()Array 构造函数对于关联数组不是;它仅适用于数字索引数组。对象本身在 JavaScript 中兼作关联数组。

function get_array_from_XML(XML_node){
    var XML_array = new Object();
    // -------------------^
    var child_node;

    for(var i=0; i<XML_node.childNodes.length; i++){
        child_node = XML_node.childNodes[i];
        if(child_node.childNodes[0]){
            if (child_node.childNodes[0].nodeType == 3){
                XML_array[child_node.nodeName] = child_node.childNodes[0].nodeValue;
            } else {                
                XML_array[child_node.nodeName] = get_array_from_XML(child_node);
            }
        }
    }

    dump(XML_array);  //for my debugging, alerts "LEVEL_2 => VALUE", so everything seems fine

    return XML_array;
}

将对象用作关联数组

看看下面的例子:

var colors = new Object();
colors['red'] = '#f00';
colors['green'] = '#0f0';
colors['blue'] = '#00f';
colors['black'] = '#000';
colors['white'] = '#fff';

conosle.log(colors['red']); // => #f00
conosle.log(colors['green']); // => #0f0
conosle.log(colors['white']); // => #fff

// Use for..in or Object.keys to iterate over an object
for (var key in colors) {
    console.log(key, colors[key]);
}
// Logs all colors and their corresponding code

Object.keys(colors).forEach(function(key) {
    console.log(key, colors[key]);
});
// Also logs all colors and their corresponding code

请注意,colors['red'] = '#f00';colors.red = '#f00'; 相同。只有当你想使用一个无效标识符的字符串或者你想使用一个变量的值作为属性名时,才真正需要方括号表示法。

【讨论】:

  • Array constructor is for numerically indexed arrays only - 在使用 JS 几年后,我今天第一次偶然发现了这个问题。不敢相信它没有早点穿过我的路。感谢您提供宝贵的信息!
猜你喜欢
  • 2020-01-24
  • 2023-02-14
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多