9

这里发生了什么?

var x = {length:3, '0':'foo', '1':'bar','2':'f', splice:function(){}}

这实际上创建了一个数组:

["foo", "bar", "f"]

这种结构语法的文档在哪里?

它也很聪明:

更改为:(注意 0 、 1 、 3)

 var x = {length:3, '0':'foo', '1':'bar','3':'f', splice:function(){}}

会弄乱数组,它将是:

["foo", "bar", undefined × 1]

此外,删除拼接功能:

var x = {length:3, '0':'foo', '1':'bar','2':'f'}

产量:(常规对象)

Object
0: "foo"
1: "bar"
2: "f"
length: 3
__proto__: Object

所以我有两个问题:

  • 这是什么结构? length , element , splice

  • 假设我有['john','paul','yoko'],现在我想创建对象

    var x = {length:3, '0':'john', '1':'paul','2':'yoko', splice:function(){}}

    我该怎么做?

4

4 回答 4

6

数组只不过是一个 object,实现了一些方法,当你 make 时console.log(x),你的控制台会识别数组的模型,并像配置它一样显示它。

ArrayJavascript中默认可用的对象,它的处理方式与浏览器的其他对象略有不同(请参阅@MathiasSchwarz 评论),但在其结构中,它与其他对象一样(您可以调用一些方法,并且您可以添加索引。不过,您通常不会像在“普通”对象中那样使用字符串索引,因为它的目标不是那样使用)。

但是您的对象并不是真正的Array,您可以做任何您想做的事情,而无需参考控制台中显示的内容。

于 2012-10-29T09:49:18.240 回答
3

x不是数组,它只是一个对象。(控制台以数组形式显示,是控制台实现的问题。

var x = {length:3, '0':'foo', '1':'bar','2':'f', splice:function(){}};
console.log(typeof x); // object

以firebug为例,看一下firebug的源代码,你就会明白为什么控制台认为它是一个数组。

//...
isArray: function(obj, win)
{
    if (mightBeArray(obj, win))
    {
        if (!obj)
            return false;
        // do this first to avoid security 1000 errors
        else if (obj instanceof Ci.nsIDOMHistory)
            return false;
        // do this first to avoid exceptions
        else if (obj.toString && obj.toString() === "[xpconnect wrapped native prototype]")
            return false;
        else if (isFinite(obj.length) && typeof obj.splice === "function")
            return true;
        else if (Arr.isArray(obj))
            return true;
    }

    return false;
},
// ...
于 2012-10-29T09:50:36.963 回答
2
var x = {length:3, '0':'foo', '1':'bar','2':'f', splice:function(){}}

看起来像一个数组,但不是。如果你尝试x.forEach(function(e){...})它失败,但如果你这样做[1,2,3].forEach(function(e){...})

如果你想通过文字对象表示法创建一个实际的数组,你可以这样做

var x = {length:3, ... , __proto__:Array.prototype}

但是请注意,像这样创建的对象仍然不会length在写入时更新其属性。

具有长度和数字索引的对象称为伪数组是 Javascript。其中一个例子是 jQuery 对象。

Chrome 控制台 将带有 a和的对象显示为数组,但这并不意味着它们数组。lengthsplice

于 2012-10-29T09:58:55.290 回答
0

创建的对象不是一个数组,但它会表现得像一个数组(虽然是不可变的),因为它有一个长度字段和一个splice方法。

在 JavaScript 数组中,该length字段会在数组更新时自动更新。对于您的对象,情况并非如此。在您的对象中,无论对象包含什么,该length字段都将保留。3这也是当您将索引更改为 0、1、3 时事情不再起作用的原因。在这种情况下,长度字段应该是4而不是3。由于值是3迭代将在索引 2 之后停止,这确实是未定义的,因为您没有为索引 2 设置值...

于 2012-10-29T10:03:09.040 回答