javascript数组关联和索引?

puf*_*pio 38 javascript arrays indexing associative

JS中的数组是否可以关联和索引?我希望能够通过其位置或键值查找数组中的项目..可能吗?

Ale*_*ski 28

Javascript中没有关联数组这样的东西.您可以使用对象文字,它们看起来像关联数组,但它们具有无序属性.常规Javascript数组基于整数索引,不能是关联的.

例如,使用此对象:

var params = {
    foo: 1,
    bar: 0,
    other: 2
};
Run Code Online (Sandbox Code Playgroud)

您可以从对象访问属性,例如:

params["foo"];
Run Code Online (Sandbox Code Playgroud)

您还可以使用以下for...in语句迭代对象:

for(var v in params) {
    //v is equal to the currently iterated property
}
Run Code Online (Sandbox Code Playgroud)

但是,对属性迭代的顺序没有严格的规则 - 对象文字的两次迭代可以返回不同顺序的属性.

  • JavaScript对象(包括数组)只有**字符串索引.`a [1]`实际上是在说'a ['1']`. (6认同)
  • 你的意思是像一个字符串?在这种情况下,它不是一个数组,只是一个具有属性的对象. (3认同)
  • Nosredna:JS数组没有关键索引,那些JS对象被认为是对象文字.所以:foo ["bar"] = 1; foo.bar === foo ["bar"]; // true foo ["bar"] === foo [0]; // false这是关于JS的许多微妙的怪癖之一,可以轻松地让人们失望. (3认同)

Nos*_*dna 22

在阅读了关联数组维基百科定义之后,我将打破传统的JavaScript传说并说"是的,JavaScript确实有关联数组." 使用JavaScript数组,您可以通过其键添加,重新分配,删除和查找值(并且键可以是引用的字符串),这是维基百科所说的关联数组应该能够做到的.

但是,您似乎在问一些不同的东西 - 您是否可以通过索引或键查找相同的值.这不是关联数组的要求(请参阅维基百科文章.)关联数组不必为您提供通过索引获取值的能力.

JavaScript数组非常类似于JavaScript对象.

  arr=[];
  arr[0]="zero";
  arr[1]="one";
  arr[2]="two";
  arr["fancy"]="what?";
Run Code Online (Sandbox Code Playgroud)

是的,这是一个数组,是的,你可以逃脱非数字索引.(如果你很好奇,毕竟这个,arr.length是3.)

在大多数情况下,我认为在使用数组时应该坚持使用数字索引.我认为这是大多数程序员所期望的.

链接是关于该主题的我的博客文章.

  • 为了迂腐,"fancy"不是数组中的索引,而是数组实例对象的属性. (14认同)
  • 这根本不是迂腐.这是一个非常重要的区别,当您开始尝试将数组序列化为JSON时,这一点很明显.使用非数字键的值是_not_数组数据的一部分.(严格地说,你不使用`.push()`来破坏你的数组.) (5认同)
  • @BaroqueBobcat:真是迂腐:)数组中的索引只是数组实例对象的属性("属性"); 数组只是特别处理那些与length属性有关的整数字符串形式的属性. (3认同)
  • 我不赞成这个答案,因为虽然可以使用看起来像数组的语法,但这不是正确的 javascript,也不是正确的数组。您的回答很适合参考,但应该明确提醒您,这不是您通常使用数组的方式。 (3认同)

Chr*_*oph 9

本机JS对象只接受字符串作为属性名称,即使对于数字数组索引也是如此; 数组与vanilla对象的区别仅在于大多数JS实现将以不同方式存储数字索引属性(即在实际数组中只要它们是密集的)并且设置它们将触发附加操作(例如,length属性的调整).

如果您正在寻找接受任意键的映射,则必须使用非本机实现.该脚本用于快速迭代,而不是数字索引的随机访问,因此它可能也不是您正在寻找的.

一个地图的准确实现可以满足您的需求,如下所示:

function Map() {
    this.length = 0;
    this.store = {};
}

Map.prototype.get = function(key) {
    return this.store.hasOwnProperty(key) ?
        this.store[key] : undefined;
};

Map.prototype.put = function(key, value, index) {
    if(arguments.length < 3) {
        if(this.store.hasOwnProperty(key)) {
            this.store[key].value = value;
            return this;
        }

        index = this.length;
    }
    else if(index >>> 0 !== index || index >= 0xffffffff)
        throw new Error('illegal index argument');

    if(index >= this.length)
        this.length = index + 1;

    this[index] = this.store[key] =
        { index : index, key : key, value : value };

    return this;
};
Run Code Online (Sandbox Code Playgroud)

index的说法put()是可选的.

您可以map通过键或索引来访问映射中的值

map.get('key').value
map[2].value
Run Code Online (Sandbox Code Playgroud)


Mat*_*ges 6

对象在关联javascript数组中出现的顺序未定义,并且在不同的实现中会有所不同.因此,您无法真正指望给定的关联键始终位于同一索引处.

编辑:

正如Perspx指出的那样,javascript中没有真正真正的关联数组.声明foo["bar"]只是语法糖foo.bar

如果您信任浏览器来维护对象中元素的顺序,则可以编写一个函数

function valueForIndex(obj, index) {

    var i = 0;
    for (var key in obj) {

        if (i++ == index)
            return obj[key];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然这是真的,但实际上所有主流浏览器都按照定义它们的顺序循环对象的属性.当然,这不在规范中,但值得一提. (3认同)

Tom*_*ats 6

var myArray = Array();
myArray["first"] = "Object1";
myArray["second"] = "Object2";
myArray["third"] = "Object3";

Object.keys(myArray);              // returns ["first", "second", "third"]
Object.keys(myArray).length;       // returns 3
Run Code Online (Sandbox Code Playgroud)

如果你想要第一个元素,那么你可以像这样使用它:

myArray[Object.keys(myArray)[0]];  // returns "Object1"
Run Code Online (Sandbox Code Playgroud)