2009-05-17 115 views
87

下面的两个不同的代码片段似乎等同于我:数组与对象有什么区别?

var myArray = Array(); 
myArray['A'] = "Athens"; 
myArray['B'] = "Berlin"; 

var myObject = {'A': 'Athens', 'B':'Berlin'}; 

,因为它们都具有相同的行为,也typeof(myArray) == typeof(myObjects)(包括产量“对象”)。

这些变体之间有区别吗?

回答

107

几乎所有的JavaScript是一种对象,这样你就可以“滥用”的Array对象通过它设置任意属性。这should be considered harmful虽然。数组用于数字索引的数据 - 对于非数字键,使用Object。

这里有一个更具体的例子,为什么非数字键不“适合”的Array:

var myArray = Array(); 
myArray['A'] = "Athens"; 
myArray['B'] = "Berlin"; 

alert(myArray.length); 

这将不显示“2”,而是“0” - 有效,没有任何元素已经添加到数组中,只是添加到数组对象的一些新属性。

+2

myArray.length返回数组中最后一个元素的数字索引/键,但不是实际元素数。 Array对象的属性与数组值不同? – 2009-05-17 09:50:19

+1

我只是试图说明Array对象的预期语义被滥用,如果你只是把它当作普通对象来对待。链接的文章做得更好:) – 2009-05-17 10:19:26

+5

下次有人说JavaScript是一种很好的开发语言时,我会向他展示这个示例。谢谢。 – 2014-04-19 08:04:49

-1

{} -notation只是语法糖使代码更好;-)

JavaScript有许多相似的结构,如功能,施工,其中()函数仅仅是

var Func = new Function("<params>", "<code>"); 
的代名词
+3

功能构造是**不**的功能文字的代名词。文字是词法作用域,而构造函数是全局的。 '{}'是文字对象表示法,'[]'是文字数组,我不确定你的答案是什么。 – 2011-04-21 17:11:17

+0

另外,声明的函数在任何代码执行之前都可用,使用函数构造函数的赋值在创建它们的代码执行之前不可用。 – RobG 2014-09-11 02:52:58

13

在JS数组中是对象,只是稍作修改(有几个更多的功能)。

功能,如:

concat 
every 
filer 
forEach 
join 
indexOf 
lastIndexOf 
map 
pop 
push 
reverse 
shift 
slice 
some 
sort 
splice 
toSource 
toString 
unshift 
valueOf 
+0

尽管我不认为列出的所有函数都内置在每个JS实现中,但您明白了。另一个区别将是不同的原型(这是由这些额外功能所暗示的)。 – Rashack 2009-05-17 09:26:40

5

JavaScript中的所有内容都是除原始类型之外的对象。

代码

var myArray = Array(); 

var myObject = {'A': 'Athens', 'B':'Berlin'}; 

创建对象对象的实例创建Array对象的一个​​实例。

试试下面的代码

alert(myArray.constructor) 
alert(myObject.constructor) 

所以你会看到不同的是在对象的构造函数的类型。

Array对象的实例将包含Array原型的所有属性和方法。

4

我认为,我对以前的回答太隐喻和隐晦。澄清如下。

Array,Boolean,Date,Function,Number,RegExp,String的一个实例是一个对象,但增强了特定于每种类型的方法和属性。例如,数组具有预定义的length属性,而通用对象则不具有。

javascript:alert([].length+'\n'+{}.length) 

显示器

 
0 
undefined 

本质,则FF壁虎解释器还区分阵列,并用显着差异评估语言构造的通用对象之间。

javascript: 
    ra=[ "one", "two", "three"]; ra.a=4; 
    ob={0:"one", 1:"two", 2:"three"}; ob.a=4; 
    alert(
    ra   +"\n\n"+ 
    ob   +"\n\n"+ 
    ra.toSource() +"\n\n"+ 
    ra.a   +"\t .toSource() forgot me! \n\n"+ 
    ra.length  +"\t and my length! \n\n"+ 
    ob.toSource()); 
    ps=""; for(i in ra)ps+=i+" "; alert(ps); /* NB .length is missing! */ 
    ps=""; for(i in ob)ps+=i+" "; alert(ps); 

显示

 
one,two,three 

[object Object] 

["one", "two", "three"] 

4 .toSource() forgot me! 

3 and my length! 

({0:"one", 1:"two", 2:"three", a:4}) 

0 1 2 a0 1 2 a和。

关于所有对象都是函数的语句:

这既不是语法上也不语义正确使用任意对象实例像123()"abc"()[](){}()obj()的函数,其中obj比其他任何类型因此任意对象INSTANCE不是Function。然而,给定一个对象obj,它的类型为Array, Boolean, Date, ...obj是如何作为Array, Boolean, Date, ...?什么是Array, Boolean, Date, ...

javascript: 
    alert([Array, Boolean, Date, Function, 
       Number, Object, RegExp, String] . join('\n\n')); 

显示器

function Array() { 
    [native code] 
} 

function Boolean() { 
    [native code] 
} 

function Date() { 
    [native code] 
} 

function Function() { 
    [native code] 
} 

function Number() { 
    [native code] 
} 

function Object() { 
    [native code] 
} 

function RegExp() { 
    [native code] 
} 

function String() { 
    [native code] 
} 

在每种情况下,毫不含糊,对象类型表现为function定义,因此,所有对象都是函数的声明! (我的意思是我故意掩盖并模糊了对象实例与它的类型的区别!但是,这表明“你不能没有其他实例”,Object和Function!Capitalization强调类型为反对实例。)

两者的功能和对象范似乎根本到编程和执行JS解释低电平内置原语,如MathJSONtrue

javascript:alert([Math, JSON, true.toSource()].join("\n\n")); 

显示

[object Math] 

[object JSON] 

(new Boolean(true)) 

在JavaScript中,对象为中心的编程风格(OOP的开发时间 - 面向对象的编程风格 - 将“的”是我自己的双关语!)流行起来,口译员被类似的Java命名,以增强其可信度。函数式编程技术被归入研究自动机,递归函数,形式语言等等的理论的更抽象和深奥的考试,并且因此不如可口。然而,这些正式考虑的优势在Javascript中明显体现出来,特别是在FF的Gecko引擎中实现(例如,.toSource())。


函数的对象定义特别令人满意,因为它被定义为递归关系!使用它自己的定义来定义!

function Function() { [native code] }
并且由于功能是用于
function Object() { [native code] }对象相同的情绪成立。

大多数其他定义静默终端价值。但是,eval()是一个特别强大的原语,因此字符串也可以嵌入任意功能。

再次注意,上面使用的白话模糊了对象类型和实例的区别。上array所有非数字指标被忽略使用JSON.stringify

1

一个实际的区别是:

var arr = []; 
var obj = {}; 

arr['name'] = 'John'; 
obj['name'] = 'John'; 

console.log(arr); // will output [name: "John"] 
console.log(obj); // will output {name: "John"} 

JSON.stringify(arr); // will return [] 
JSON.stringify(obj); // will return {"name":"John"}