这里发生了什么?
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']
,现在我想创建 objectvar x = {length:3, '0':'john', '1':'paul','2':'yoko', splice:function(){}}
我该怎么做?
一个数组无非是对象,并实现了某些方法,当您制作console.log(x)
时,您的控制台会识别数组的模型,并像显示一样显示它已配置为这样做。
Array
是默认情况下 javaScript 中的一个对象,它的处理方式与浏览器的处理方式有所不同(请参阅@mathiasschwarz的注释),但在其结构上,它是一个像对象其他(您可以调用方法,您可以添加索引。但是,您通常不会使用像"正常"对象中的字符串索引,因为它不是为了这样使用)。
但是您的对象不是真正的Array
,您可以做任何您想做的事情,而无需参考控制台中显示的内容。
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;
},
// ...
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}
注意,但是,像这样创建的对象 still 不会更新它的 length
属性。
具有长度和数字索引的对象称为 pseudo-arrays 是javaScript。这些的例子是jQuery对象。
Chrome Console 以length
和splice
作为数组显示对象,但这并不意味着它们是 arrays。
创建的对象是不是一个数组,但是它的行为将以一个(不可变的)(不可变),因为它具有长度字段和splice
方法。
在JavaScript数组中,当数组更新时,length
字段将自动更新。您的对象并非如此。在您的对象中,无论对象包含什么,length
字段都将保留3
。这也是为什么当您将索引更改为0,1,3时,事情不再起作用的原因。在这种情况下,长度字段应为4
,而不是3
。由于该值为3
迭代将在索引2之后停止,这确实是不确定的,因为您没有为索引2设置值...