这里发生了什么?
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(){}}
我该怎么做?
答案 0 :(得分:6)
数组只是一个对象,实现了一些方法,当你创建console.log(x)
时,你的控制台会识别一个数组的模型,并显示它已经配置好了这样做。
Array
是默认情况下在 Javascript 中可用的对象,它的处理方式与浏览器的其他对象略有不同(请参阅@MathiasSchwarz注释),但在其结构中,它是一个像其他人一样的对象(你可以调用你的方法,你可以添加索引。但是,你通常不会使用#"普通"对象之类的字符串索引,因为它& #39;不打算像那样使用。)
但你的对象实际上并不是Array
,你可以随意做任何事情,而无需参考控制台中显示的内容。
答案 1 :(得分: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;
},
// ...
答案 2 :(得分: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控制台 显示带有length
和splice
数组的对象,但这并不意味着 arrays。
答案 3 :(得分:0)
创建的对象不是一个数组,但它将表现为一个(虽然不可变),因为它有一个长度字段和一个splice
方法。
在JavaScript数组中,更新数组时会自动更新length
字段。对于您的对象,情况并非如此。在您的对象中,无论对象包含什么内容,length
字段都将保留3
。
这也是将索引更改为0,1,3时不再起作用的原因。在这种情况下,长度字段应该是4
而不是3
。由于值为3
,因此迭代将在索引2之后停止,因为您没有为索引2设置值,所以它确实是未定义的...