数组是关联的还是索引的?

IT技术 javascript arrays indexing associative
2021-02-02 10:16:45

JavaScript 中的数组可以关联和索引吗?

我希望能够通过其位置或键值在数组中查找项目。

6个回答

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

例如,对于这个对象:

var params = {
    foo: 1,
    bar: 0,
    other: 2
};

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

params["foo"];

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

for(var v in params) {
    //v is equal to the currently iterated property
}

但是,属性迭代的顺序没有严格的规则——对象字面量的两次迭代可能会以不同的顺序返回属性。

最新的 MDN 文档清楚地表明 Array 索引必须是整数。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-03-18 10:16:45
你的意思是像一个字符串?在这种情况下,它不是一个数组,而只是一个具有属性的对象。
2021-03-22 10:16:45
JavaScript 对象,包括数组,只有字符串索引。a[1]其实是说a['1']
2021-03-23 10:16:45
实际上,JavaScript 数组也可以有非整数索引。它只是没有太多处理它们的方法。
2021-04-14 10:16:45
Nosredna:JS 数组没有键索引,那些 JS 对象被认为是对象字面量。所以: foo["bar"] = 1; foo.bar === foo["bar"]; //真 foo["bar"] === foo[0]; //false 这是关于 JS 的许多微妙的怪癖之一,它很容易让人们失望。
2021-04-14 10:16:45

在阅读了Wikipedia 对关联数组的定义后,我将打破传统的 JavaScript 知识并说:“是的,JavaScript 确实有关联数组。” 使用 JavaScript 数组,您可以通过它们的键添加、重新分配、删除和查找值(并且键可以是带引号的字符串),这是维基百科所说的关联数组应该能够做到的。

但是,您似乎在问一些不同的问题——是否可以通过索引或键查找相同的值。这不是关联数组的要求(请参阅 Wikipedia 文章。)关联数组不必让您能够通过索引获取值。

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

  arr=[];
  arr[0]="zero";
  arr[1]="one";
  arr[2]="two";
  arr["fancy"]="what?";

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

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

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

当您说“并且您可以拥有一个具有非数字索引的数组”时,您是对的。不知怎的,我忘记了这一点,但我知道这个事实。
2021-03-17 10:16:45
我不赞成这个答案,因为虽然可以使用看起来像数组的语法,但这不是正确的 javascript,也不是正确的数组。您的回答很适合参考,但应该明确提醒您,这不是您通常使用数组的方式。
2021-03-20 10:16:45
迂腐说,“fancy”不是数组中的索引,而是数组实例对象的一个​​属性。
2021-04-08 10:16:45
@BaroqueBobcat:真的很迂腐:) 数组中的索引只是数组实例对象的属性(“属性”);一个数组只特别处理那些关于长度属性的整数字符串形式的属性。
2021-04-09 10:16:45
这一点也不迂腐。这是一个非常重要的区别,当您开始尝试将数组序列化为 JSON 时就很明显了。具有非数字键的值不是数组数据的一部分。(严格来说,您不使用.push().会破坏您的数组。)
2021-04-11 10:16:45

原生 JS 对象只接受字符串作为属性名称,即使对于数字数组索引也是如此数组与普通对象的不同之处仅在于大多数 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;
};

index参数put()是可选的。

您可以map通过键或索引访问地图中的值

map.get('key').value
map[2].value
你怎么放?map.put('key','value') 和 map[2].value = val ?
2021-03-28 10:16:45
+1,但我会丢失“数字索引的属性将以不同的方式存储”:情况不一定如此,规范也不需要。
2021-04-02 10:16:45
map.put('key','value')用于附加值和map.put('key','value', 42)在给定位置插入值;map[42].value = 'value'也可以工作(即替换现有键值对的值),但您不能以这种方式更改条目的键或索引或添加新条目
2021-04-12 10:16:45
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

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

myArray[Object.keys(myArray)[0]];  // returns "Object1"

对象出现在关联 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];
    }
}
JavaScript 没有关联数组。您的答案是在谈论对象,而不是数组。
2021-03-21 10:16:45
尽管这是真的,但实际上所有主要浏览器都按照定义的顺序循环遍历对象的属性。这当然不在规范中,但值得一提。
2021-03-23 10:16:45