Why does typeof array with objects return “object” and not “array”?
Possible Duplicate:
JavaScript: Check if object is array?
为什么一个对象数组被认为是一个对象而不是一个数组?例如:
1 2 3 4 5 6 7 8 9
| $.ajax({
url: 'http://api.twitter.com/1/statuses/user_timeline.json',
data: { screen_name: 'mick__romney'},
dataType: 'jsonp',
success: function(data) {
console.dir(data); //Array[20]
alert(typeof data); //Object
}
});? |
小提琴
- 这就是定义typeof的方式,但您可以使用Array.isArray。
- 奇怪的是,这是另一个问题的复制品,看起来完全不同…
Javascript中一个奇怪的行为和规范是类型数组是Object。
您可以通过以下两种方式检查变量是否为数组:
1 2
| var isArr = data instanceof Array;
var isArr = Array.isArray(data); |
但最可靠的方法是:
1
| isArr = Object.prototype.toString.call(data) == '[object Array]'; |
由于您将问题标记为jquery,因此可以使用jquery isArray函数:
1
| var isArr = $.isArray(data); |
- 换句话说,typeof永远不能返回"array"?
- "但最可靠的方法是:…"所以你建议的其他方法是不可靠的?
- @亚历克斯,是的,另一个可以给你一个false,如果你在检查从得到的数组。
- @gdoron mdn似乎表明Array.isArray(…)应该是可靠的开发人员。mozilla.org/en-us/docs/web/javascript/reference/…?
- @M,您是对的,但旧浏览器不支持。看到这里
- 您可以使用以下方法确定是否有数组或对象:if(typeof myArrayOfObject[0] =="object")。如果true,那么你有对象;如果false,那么你有数组。
引用规范
15.4阵列对象
Array objects give special treatment to a certain class of property names. A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2^32-1. A property whose property name is an array index is also called an element. Every Array object has a length property whose value is always a nonnegative integer less than 2^32. The value of the length property is numerically greater than the name of every property whose name is an array index; whenever a property of an Array object is created or changed, other properties are adjusted as necessary to maintain this invariant. Specifically, whenever a property is added whose name is an array index, the length property is changed, if necessary, to be one more than the numeric value of that array index; and whenever the length property is changed, every property whose name is an array index whose value is not smaller than the new length is automatically deleted. This constraint applies only to own properties of an Array object and is unaffected by length or array index properties that may be inherited from its prototypes.
这是给typeof的桌子
要添加一些背景,javascript中有两种数据类型:
基本数据类型-包括空、未定义、字符串、布尔值、数字和对象。
派生数据类型/特殊对象-包括函数、数组和正则表达式。是的,这些都是从JavaScript中的"对象"派生的。
javascript中的对象在结构上与大多数面向对象语言中看到的关联数组/字典相似,即它有一组键值对。
可以将数组视为具有以下属性/键的对象:
长度-可以是0或以上(非负)。
数组索引。我的意思是"0"、"1"、"2"等都是数组对象的属性。
希望这有助于解释为什么typeof数组返回对象。干杯!
- 根据:developer.mozilla.org/en-us/docs/glossary/primitive,对象不是原语
尝试这个例子,您将了解到在javascript中关联数组和对象之间的区别。
关联数组
1 2 3
| var a = new Array(1,2,3);
a['key'] = 'experiment';
Array.isArray(a); |
返回EDOCX1[4]
请记住,a.length将是未定义的,因为length被视为一个键,您应该使用Object.keys(a).length来获取关联数组的长度。
对象
1 2
| var a = {1:1, 2:2, 3:3,'key':'experiment'};
Array.isArray(a) |
返回false。
JSON返回一个对象…无法返回关联数组…但不是那样的
- JSON还有数组的概念。(数组索引从0开始。)
- 那家伙把他的数据定义为…} -对象…我试图向他解释关联数组和对象的区别是什么。实际上,他检查服务器返回的日期,所以不一样…但也许你是对的…应该检查一下:)
- 你能举个联合数组的例子吗?像这样:jQuery.parseJSON('{"name":"John"}')…这个通常被认为是一个对象。您认为JSON如何表示一个关联数组?
- JSON中没有所谓的关联数组。但我不确定你在回答这个问题时想说什么。
- 恕我直言,在javascript中有一种叫做关联数组的东西…检查一下…这就是我试图解释的…当你叫isArray时,你的尊重是什么?例如,关联数组是Perl中的散列,或者通常称为字典。JSON没有这种表示方式..因此关联数组被视为具有属性的对象。
- 但这是如何回答这个问题的呢?OP有一个数组,EDOCX1 0给出EDCOX1×11。他想知道为什么会这样。简而言之,问题是:为什么typeof []不给出EDCX1〔13〕?你并没有真正回答这个问题。
- 回答了JSON返回一个对象,而不是一个数组的一半,并给出了一些额外的信息,因为语法JSON总是将数组解析为对象而不是关联数组,这可能是因为关联数组作为一个类型存在,但不幸的是JSON不是这样工作的,并且不返回关联数组。关联数组有一些缺点,使用对象是很好的。举个例子,我在回答中解释了这一点。因此,我们的想法是理解为什么他们使用对象解析JSON字符串。至少你学到了一些东西。对吗?
- 这里的json没有什么问题;data实际上是一个数组。OP根本不使用关联数组。问题是,当在数组上使用时,为什么typeof会给"object"。但我想我们说的是不同的波长。
- { key: value }定义的是一个对象,而不是一个数组。正如您所知道的,要定义一个数组,您应该执行['mick__romney']操作。另一件事是,guy检查的data是Ajax请求解析器的结果,它与Ajax设置中的参数data:没有任何共同之处。答案是JSON将JSON字符串传递的所有数组转换为对象。不能被区分,不管它们看起来像一个数组。有很多方法可以解决前try { var a = data.scrren_name; isArray = true; } catch (e) { isArray = false;}的问题…但是深入研究这个问题是很好的。
- 总之…继续谈论它是没有用的:)让我们调整一下"最新问题"频道;
- JSON绝对不会"将JSON字符串传递给对象的所有数组都翻译成"。解析后,这些数组(使用方括号)将成为实际的JS数组,而不是对象。另外,在您答案A的第一个示例中,长度不会是未定义的,它将是3。
- 关于.length—您应该首先尝试(如上面的示例所示)。will be并不意味着it is…并清楚地解释了原因。关于数组:我说的是关联数组,可能不太清楚,因为我写了100行,可能我错过了解释。但请告诉我,JSON中如何表示关联数组?回答你自己这个问题将最终结束这个无休止的讨论。当你发现.length不适用于关联数组时,勇敢地说:"好吧,我的错误。"
- 数组的json表示:"[1,2,3]"—解析后将创建数组[1,2,3],该数组具有3的.length,对于该数组,Array.isArray()将返回true。也就是说,Array.isArray(JSON.parse("[1,2,3]"))就是true(试试看)。在您的答案中,您所称的"关联数组"是一个标准的JS数组,它添加了额外的非数字属性,并且不能在JSON中表示(除了必须转换为数组的非数组对象)。
- 另外,在你的例子中,a.length将是3——你试试看,你就是在这里弄错的那个。length属性将比数组中的最高数字索引属性高一个,即它忽略了您添加的任何其他非数字属性,例如您的a['key']示例-但length不会是未定义的-也许这就是您想说的。在其他语言中存在一个"关联数组",但在JavaScript中,最接近的是一个纯对象。
- 可能这取决于我的主浏览器,但无论如何,它的长度不正确…如果你只有钥匙,它将是0,但我很高兴你终于明白我在说什么。我不是说数组"[1,2,3]",它绝对是正规数组。仔细阅读。添加键"key"使其成为关联键(hash、dictionary)。不是我给的名字,这就是它的名字。最后一次:有一个不同的b/w关联数组和对象-isarray将返回true作为关联数组,false作为对象。Google:关联数组javascript
- 读你的答案,我想你从来没有听说过联想数组,也不相信它们的存在:)不管怎样,这种讨论是无用的。我不会把时间花在容易检查的东西上。
代码中没有普通的JS数组。data是本机JS对象。注意不同类型括号的不同含义:
1 2
| var someArray = [];
var someObject = {}; |
- 是的,但它仍然被包装在一个数组中。所以在我看来,它仍然应该返回数组。
- "数据是本机JS对象"—不,操作程序询问success函数中的data参数(如果解析的JSONP响应是这样的话,那么它将是一个数组)。