阵列只是伪装的对象吗?为什么/为什么不呢?它们是以什么方式(这样/不是)?
我一直认为JS中的数组和对象基本相同,主要是因为访问它们是相同的。
var obj = {'I': 'me'};
var arr = new Array();
arr['you'] = 'them';
console.log(obj.I);
console.log(arr.you);
console.log(obj['I']);
console.log(arr['you']);
我是误导/错误/错误吗?关于JS文字,基元和字符串/对象/数组/等,我需要了解什么??
数组/对象只是伪装的字符串吗?为什么/为什么不呢?它们是以什么方式(这样/不是)?
答案 0 :(得分:31)
数组是对象。
但是,与常规对象不同,数组具有某些特殊功能。
数组在其原型链中有一个额外的对象 - 即Array.prototype
。该对象包含所谓的Array方法,可以在数组实例上调用。 (方法列表在这里:http://es5.github.com/#x15.4.4)
数组有length
属性(现场,ergo,自动更新)(请参阅此处:http://es5.github.com/#x15.4.5.2)
数组有一个关于定义新属性的特殊算法(请参阅此处:http://es5.github.com/#x15.4.5.1)。如果你将一个新属性设置为一个数组,并且该属性的名称是一个可以强制转换为整数的sting(如'1'
,'2'
,'3'
等),那么特殊的算法适用(在规范中的第123页定义)
除了这三件事之外,数组就像常规对象一样。
了解规范中的数组:http://es5.github.com/#x15.4
答案 1 :(得分:8)
对象是从字符串键到值的无序映射,数组是有序的值列表(使用整数键)。这是主要的区别。它们都是非原始的,因为它们由多个值组成,这也暗示了JavaScript中的pass-by-reference。
但是,数组也是一种对象,所以你可以为它们附加额外的属性,访问它们的原型等等。
在您修改过的示例中,您只是利用了一个数组实际上是一个对象的事实,即您可以在它们上设置任何属性。你不应该这样做。如果您不需要有序的值列表,请使用普通对象。
答案 2 :(得分:6)
字符串可以是原始字符串或对象,具体取决于它们的声明方式。
var str = 'yes';
给你一个原语,而
var str = new String('yes');
会给你一个String对象。
所有数组都是相同的(无论它们是否使用[]或新的Array()定义)都属于对象类型并且继承自“Array”对象的原型。 Javascript中没有真正的类,一切都是对象,并且有一个名为Array的系统定义对象。它有一个名为'prototype'的属性(类型为object),当你在具有prototype属性的对象上使用new关键字时,它会创建一个实例,其中包含对原型内容的引用并将其存储在变量中。因此,您在Javascript中使用的所有数组都是Array的原型属性的对象和实例。
在任何情况下,虽然数组确实是对象,但由于它们有用的属性和功能(如长度,切片,推送等),它们的行为类似于数组。
另一个注意事项,虽然我说没有课程,但是当你这样做时:
console.log(Object.prototype.toString.call(your_object));
它将以[object Object]的形式为您提供一个字符串。但有用的是,当你用数组调用它时,你得到的[object Array]与给出[object Function]和许多其他系统定义类型的函数相同,这有助于区分普通对象和数组(由于typeof operator始终只返回字符串'object')。
试试这个
var a = Array;
然后进入萤火虫并检查a的内容,特别是它的'原型'属性。
修改:改变措辞,更正确。实际上,当您使用new关键字时,它会创建一个引用原型对象的实例。因此,在实例声明之后对原型所做的任何更改仍将影响实例。
编辑:在回答您最新修订的问题时(数组/对象实际上是伪装的字符串):否。正如我所解释的那样,它们是对象。字符串可以是基本类型,也可以是对象类型(String对象的实例),它包含与其中一个属性相同的原语。
答案 3 :(得分:3)
数组中的数组不是原语,它们是对象。关键的区别在于,当您将数组传递给函数时,它将通过引用而不是值传递。
是的!数组是javascript中的对象,具有完整的Array.prototype和所有内容(尽管如此......不要触摸它)。
混淆来自于javascripts允许您以两种方式访问对象属性:
myObj.attribute 要么 MyObj中[ “属性”]
真正使数组成为数组与存储数据的方式无关 - 任何对象都可以使用您用来存储数组的语法来存储值 - 数组是数组的原因是数组方法的事实(例如,为Array.prototype定义了shift()和sort())。
答案 4 :(得分:1)
尝试简要介绍我认为最重要的内容:数组有许多对象不具备的方法。包括:
声明为var x = {foo:bar}
的对象无法访问.length()方法。它们都是对象,但是使用上面提到的方法将数组作为一种超集。
我觉得我在解释方面并不接近Crockford标准,但我试图简洁。
如果您想获得一些快速结果,请打开Firebug或您的javascript控制台并尝试使用Array.prototype和Object.prototype查看一些详细信息
更新:在您的示例中,您声明了一个数组,然后执行:
foo['bar'] = 'unexpectedbehaviour';
会产生意想不到的结果,并且不会在简单的循环中提供,例如:
var foo=[0,1];
foo['bar'] = 2;
for(var i=0;i<foo.length;i++){
console.log(foo[i]);
}
//outputs:
//0
//1
数组可以像对象一样接受foo['bar']=x
或foo.bar=y
但不一定可以循环使用,如上所示。
并非我说你不能遍历对象的属性,只是在使用数组时,你正在利用这个独特的功能,并且应该记住不要混淆。
答案 5 :(得分:1)
在JavaScript中,您有几种类型,所有内容 else是一个对象。 JavaScript中的类型是:boolean,number和string。还有两个特殊值,“null”和“undefined”。
那么任务“是一个JavaScript数组对象吗?”有点含糊不清。是的,JavaScript数组是一个“对象”,但它不是“对象”的实例。 JavaScript数组是“Array”的实例。虽然,所有对象都继承自Object;您可以在the MDC上查看继承链。此外,数组的属性与对象略有不同。数组具有.length
属性。他们还有.slice()
,.join()
等方法。
答案 6 :(得分:0)
数组是对象,但具有特殊性质。对象是由键索引的值的集合(以Javascript表示法,{'key': 'value'}
),而数组是对象,其键是数字的(具有一些函数和属性)。当您使用for each
循环时,它们之间的关键区别是显而易见的 - 对象将迭代其属性中的所有值,而数组将返回键。 Here's指向JSFiddle的链接,演示差异 - 注意第一个使用数组的for each
返回索引,而不是值;相反,第二个for each
返回这些键的实际值。