Javascript中关联数组的[]和{}之间的差异

时间:2014-02-23 13:22:25

标签: javascript

现在实现一个简单的数据库。

我认为这个问题的重复标签是一个糟糕的判断。链接的问题对我的要求没有任何作用。

用户ID引用用户数据,我有2个选项可以执行此操作,如下所示:DB1DB2

var DB1 = {
    user: {}
};
var DB2 = {
    user: []
};

DB1.user['001'] = {
    email: 'name@email.com',
    name: 'ken'
};
DB2.user['001'] = {
    email: 'name@email.com',
    name: 'ken'
};

console.log(DB1.user['001']);
console.log(DB2.user['001']);

DB1和DB2的行为完全按预期完全相同,至少对我来说是这样。

有什么区别吗?只是一种表达{}或[]的方式?

如果不同哪一个更有效?

谢谢你的想法。

更新

非常感谢所有善意回答我的人。

我可能理解在这种情况下,关联方式的数组[]实际上是一个对象。

在这种情况下,它的行为相同(对象不是数组),很好,我知道。

所以,我想知道的是,在这种情况下,它只是表达式[]和{}的区别。

更重要的是,在这种情况下,如果它不仅是表达,多么不同,哪一个更有效,那就是我想知道的。谢谢。

UPDATE2:

好吧,这并不像很多人想的那么明显。我已经编写了如下测试代码:

var DB1 = {
    user:
    {}
};
var DB2 = {
    user: []
};
var DB3 = {
    user: []
};

for (var i = 0; i < 100000; i++)
{
    var id = ('0000' + i)
        .slice(-5);

    DB1.user[id] = {
        email: 'name@email.com',
        name: 'ken'
    };

    DB2.user[id] = {
        email: 'name@email.com',
        name: 'ken'
    };

    DB3.user[i] = {
        email: 'name@email.com',
        name: 'ken'
    };

}
//confirm the value just in case
console.log(DB1.user['00000']);
console.log(DB1.user['00001']);
console.log(DB1.user['99999']);
console.log(DB1.user['100000']);

for (var t = 0; t < 10; t++)
{
    console.log('-----------test ' + t);
    console.time('DB1');
    for (var i = 0; i < 100000; i++)
    {
        var id = ('0000' + i)
            .slice(-5);

        var data = DB1.user[id];
    }
    console.timeEnd('DB1');

    console.time('DB2');
    for (var i = 0; i < 100000; i++)
    {
        var id = ('0000' + i)
            .slice(-5);

        var data = DB2.user[id];
    }
    console.timeEnd('DB2');


    console.time('DB3');
    for (var i = 0; i < 100000; i++)
    {
        var id = ('0000' + i)
            .slice(-5);

        var id1 = id * 1;
        var data = DB3.user[id1];
    }
    console.timeEnd('DB3');
}

结果:

{ email: 'name@email.com', name: 'ken' }
{ email: 'name@email.com', name: 'ken' }
{ email: 'name@email.com', name: 'ken' }
undefined

-----------test 0
DB1: 46ms
DB2: 68ms
DB3: 28ms
-----------test 1
DB1: 39ms
DB2: 33ms
DB3: 26ms
-----------test 2
DB1: 32ms
DB2: 39ms
DB3: 25ms
-----------test 3
DB1: 57ms
DB2: 33ms
DB3: 27ms
-----------test 4
DB1: 39ms
DB2: 35ms
DB3: 27ms
-----------test 5
DB1: 39ms
DB2: 32ms
DB3: 27ms
-----------test 6
DB1: 33ms
DB2: 36ms
DB3: 26ms
-----------test 7
DB1: 39ms
DB2: 41ms
DB3: 40ms
-----------test 8
DB1: 32ms
DB2: 32ms
DB3: 28ms
-----------test 9
DB1: 36ms
DB2: 31ms
DB3: 28ms

对于100000条记录,数组DB稍微快一点,但我想我会使用关联数组样式的对象DB。

4 个答案:

答案 0 :(得分:7)

[]是一个数组文字;它相当于new Array()

{}是一个对象字面值;它相当于new Object()

如果您实际存储了一系列项目,则应该只使用数组;否则,使用对象。

答案 1 :(得分:6)

  

DB1和DB2的行为完全按预期完全相同,至少对我来说是这样。

不完全。 []创建一个数组,{}创建一个对象。在JavaScript中,标准数组aren't really arrays at all,它们只是具有某些特殊行为的对象。您可以向不是数组条目的对象添加属性,就像您可以使用任何其他对象一样。在您的示例中,您没有将数组用作数组,因此两者都有效,但如果 将数组用作数组(使用数组索引length,{{1 }},push等),只有splice版本可以正常工作,只能为您提供一个数组。

当您需要数组的功能时使用数组。只需要将名称映射到值时使用对象。如果使用数组,请确保使用正版数组索引,而不是像[]这样的非索引属性名称。 (详情如下。)

以下是您未将数组用作数组的示例:

'001'

这不会创建数组条目。证明:

DB1.user['001'] = ...;

它在名为var a = []; a['001'] = "foo"; console.log(a.length); // 0 的对象上创建一个属性,但该属性不是数组条目。相反:

"001"

a[1] = "foo";

...创建一个数组条目:

a['1'] = "foo";

为何与众不同?同样,标准数组只是具有特殊行为的对象。特殊行为的关键部分之一涉及属性名称的某个,特别是那些都是正常数字形式的数字(没有前导零)(它们仍然是字符串,即使我们采取行动就像他们的数字一样)。名称为标准数字形式的属性(在范围内,允许它们为0到2 32 -2,包括在内)是一个数组条目。


我一直在说“标准数组”,因为JavaScript正在获取类型数组(事实上,它们已经在大多数引擎中):

var a = [];
a[1] = "foo";
console.log(a.length); // 2 (see below)

类型化数组是实际数组,与var a = new Int32Array(10); “数组”完全不同。


旁注:为什么[] 2 在这里?

length

因为JavaScript数组本质上是稀疏,而我所讨论的特殊行为之一就是当你向一个符合数组条目定义的数组中添加一个属性时, var a = []; a[1] = "foo"; console.log(a.length); // 2 设置为大于编号最大的数组条目的值1。因此,即使我们的length数组只有一个条目,其a也是2。


进一步注意:JavaScript中的对象不称为“关联数组”,它主要是一个用于非常特殊数据结构的PHP术语,它具有有序的名称/值映射。在JavaScript中,我们将它们称为“对象”(主要是),或者有时称为“地图”或“字典”。与PHP的关联数组不同,它们是无序的


  

更重要的是,在这种情况下,如果不仅仅是表达,多么不同,哪一个更有效,那就是我想知道的。

由于您没有将数组用作数组,因此我希望对象版本略微更高效,因为引擎最初会尝试根据您使用数组进行优化数组,然后在执行length属性名称之类的操作时回退到对象行为。所以可能从一开始就使用一个对象。

但总的来说,JavaScript“效率”是一个非常困难的话题。一台发动机的效率在其他发动机上效率不高。即使你不相信过早优化是浪费其他领域的时间,真的是用JavaScript。显然不要做蠢事,但总的来说,等到出现性能问题然后在它出现的平台上解决这个问题(然后测试你支持的其他平台,以确保你没有引入新的问题有)。

答案 2 :(得分:2)

user: {}

创建一个对象,而

user: []

创建一个数组。数组继承自Object,因此您可以添加像这样的随机属性

DB2.user['001'] = {..};

到一个数组。例如

var myArray = [];
myArray["js"] = "awesome";
myArray.push("a");
myArray.push("b");
console.log(myArray);          // [ 'a', 'b', js: 'awesome' ]

答案 3 :(得分:0)

符号是相同的,但您正在创建不同的对象。 []是一个数组,因此您将获得原型中的所有Array methods{}是一个对象,因此您将Object methods

Array可能最适合您的场景,因为它可以确保其元素的顺序。对象中有no guarantee of the order个项目。

如果您关心订单,请使用数组[],否则请使用对象{}

效率测试

var i = 10000;
console.time('arr');
while (i--) {
    ([]);
}
console.timeEnd('arr');


i = 10000;
console.time('obj');
while (i--) {
    ({});
}
console.timeEnd('obj');

结果

arr:10.527ms
obj:8.974ms