为啥带有对象的 typeof 数组返回“object”而不是“array”? [复制]

Posted

技术标签:

【中文标题】为啥带有对象的 typeof 数组返回“object”而不是“array”? [复制]【英文标题】:Why does typeof array with objects return "object" and not "array"? [duplicate]为什么带有对象的 typeof 数组返回“object”而不是“array”? [复制] 【发布时间】:2012-10-11 09:40:50 【问题描述】:

可能重复:javascript: Check if object is array?

为什么对象数组被认为是对象,而不是数组?例如:

$.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
    
);​

Fiddle

【问题讨论】:

typeof是这样定义的,但是你可以使用Array.isArray 奇怪的是,这被标记为另一个问题的重复,看起来完全不同...... 这是因为 ECMAScript 中唯一存在的“类型”是 undefined、null、boolean、number、bigint、string、symbol 和 object。 【参考方案1】:

试试这个例子,你就会明白 JavaScript 中关联数组和对象之间的区别。

关联数组

var a = new Array(1,2,3); 
a['key'] = 'experiment';
Array.isArray(a);

返回true

请记住a.length 将是未定义的,因为length 被视为键,您应该使用Object.keys(a).length 来获取关联数组的长度。

对象

var a = 1:1, 2:2, 3:3,'key':'experiment'; 
Array.isArray(a)

返回false

JSON 返回一个 Object ... 可以返回一个 Associative Array ... 但不是这样

【讨论】:

JSON 也有数组的概念。 (并且数组索引从 0 开始。) 这家伙将他的数据定义为 ... - Object ... 我试图向他解释黑白关联数组和对象有什么区别。实际上他检查服务器返回的日期,所以它不一样......但可能你是对的......应该检查它:) 你能举一个 JSON 关联数组的例子吗?类似的东西:jQuery.parseJSON('"name":"John"') ... 这个通常被接受为一个对象。您认为 JSON 是如何表示关联数组的? JSON 中没有所谓的关联数组。但我不确定你对这个问题的回答是什么意思。 恕我直言,JavaScript 中有一个叫做关联数组的东西......检查一下......这就是我试图解释的......当你打电话给 isArray 时有什么尊重。例如,关联数组是 Perl 中的 HASH 或通常称为字典。 JSON 没有这种表示形式。所以关联数组被视为具有属性的对象。【参考方案2】:

引用规范

15.4 数组对象

数组对象对特定类别的属性名称给予特殊处理。当且仅当 ToString(ToUint32(P)) 等于 P 且 ToUint32(P) 不等于 2^32-1 时,属性名称 P(以字符串值的形式)是数组索引。属性名称为数组索引的属性也称为元素。每个 Array 对象都有一个长度属性,其值始终是小于 2^32 的非负整数。 length 属性的值在数值上大于名称为数组索引的每个属性的名称;每当创建或更改 Array 对象的属性时,都会根据需要调整其他属性以保持此不变性。具体来说,每当添加名称为数组索引的属性时,如果需要,长度属性会更改为比该数组索引的数值大一;并且每当更改长度属性时,所有名称为数组索引且值不小于新长度的属性都会被自动删除。此约束仅适用于 Array 对象的自身属性,不受可能从其原型继承的长度或数组索引属性的影响。

这是typeof的表格


添加一些背景,JavaScript中有两种数据类型:

    原始数据类型 - 这包括 null、未定义、字符串、布尔值、数字和对象。 派生数据类型/特殊对象 - 这些包括函数、数组和正则表达式。是的,这些都是从 JavaScript 中的“对象”派生而来的。

JavaScript 中的对象在结构上类似于大多数面向对象语言中的关联数组/字典 - 即,它具有一组键值对。

可以将数组视为具有以下属性/键的对象:

    长度 - 这可以是 0 或更大(非负数)。 数组索引。我的意思是“0”、“1”、“2”等都是数组对象的属性。

希望这有助于进一步了解 typeof Array 为何返回对象。干杯!

【讨论】:

对象不是原始的,根据:developer.mozilla.org/en-US/docs/Glossary/Primitive【参考方案3】:

Javascript 中一个奇怪的行为和规范是 typeof 数组是 Object

您可以通过以下几种方式检查变量是否为数组:

var isArr = data instanceof Array;
var isArr = Array.isArray(data);

但最可靠的方法是:

isArr = Object.prototype.toString.call(data) == '[object Array]';

由于您使用 jQuery 标记了您的问题,您可以使用 jQuery isArray 函数:

var isArr = $.isArray(data);

【讨论】:

也就是说,typeof 永远不能返回“Array”? "但是最靠谱的方式是:..." 那么你建议的其他方式都不靠谱? @Alex,是的,如果您正在检查从 <iframe> 获得的数组,另一个可以给您 false @gdoron MDN 似乎表明Array.isArray(…) 应该是可靠的developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…? @m,你说得对,但旧版浏览器不支持。 see here

以上是关于为啥带有对象的 typeof 数组返回“object”而不是“array”? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 typeof 函数返回“函数”?

JavaScript为啥(typeof Object)返回的是function

typeof options == 'object' && options,为啥这会返回对象值? [复制]

Javascript中判断变量是数组还是对象(array还是object)

判断是对象还是数组的方法

typeof