Javascript数组原语是什么?字符串?对象?

时间:2011-02-19 02:03:02

标签: javascript arrays javascript-objects

阵列只是伪装的对象吗?为什么/为什么不呢?它们是以什么方式(这样/不是)?

我一直认为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文字,基元和字符串/对象/数组/等,我需要了解什么??

数组/对象只是伪装的字符串吗?为什么/为什么不呢?它们是以什么方式(这样/不是)?

7 个答案:

答案 0 :(得分:31)

数组是对象。

但是,与常规对象不同,数组具有某些特殊功能。

  1. 数组在其原型链中有一个额外的对象 - 即Array.prototype。该对象包含所谓的Array方法,可以在数组实例上调用。 (方法列表在这里:http://es5.github.com/#x15.4.4

  2. 数组有length属性(现场,ergo,自动更新)(请参阅此处:http://es5.github.com/#x15.4.5.2

  3. 数组有一个关于定义新属性的特殊算法(请参阅此处:http://es5.github.com/#x15.4.5.1)。如果你将一个新属性设置为一个数组,并且该属性的名称是一个可以强制转换为整数的sting(如'1''2''3'等),那么特殊的算法适用(在规范中的第123页定义)

  4. 除了这三件事之外,数组就像常规对象一样。

    了解规范中的数组: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']=xfoo.bar=y但不一定可以循环使用,如上所示。

并非我说你不能遍历对象的属性,只是在使用数组时,你正在利用这个独特的功能,并且应该记住不要混淆。

答案 5 :(得分:1)

在JavaScript中,您有几种类型,所有内容 else是一个对象。 JavaScript中的类型是:boolean,number和string。还有两个特殊值,“null”和“undefined”。

那么任务“是一个JavaScript数组对象吗?”有点含糊不清。是的,JavaScript数组是一个“对象”,但它不是“对象”的实例。 JavaScript数组是“Array”的实例。虽然,所有对象都继承自Object;您可以在the MDC上查看继承链。此外,数组的属性与对象略有不同。数组具有.length属性。他们还有.slice().join()等方法。

道格拉斯·克罗克福德提供了一种很好的survey语言功能。他的调查讨论了你所要求的差异。此外,您可以阅读有关问题#4559207 {/ 3}}的更多信息。

答案 6 :(得分:0)

数组是对象,但具有特殊性质。对象是由键索引的值的集合(以Javascript表示法,{'key': 'value'}),而数组是对象,其键是数字的(具有一些函数和属性)。当您使用for each循环时,它们之间的关键区别是显而易见的 - 对象将迭代其属性中的所有值,而数组将返回键。 Here's指向JSFiddle的链接,演示差异 - 注意第一个使用数组的for each返回索引,而不是值;相反,第二个for each返回这些键的实际值。