数组和对象有什么区别?
以下两个不同的代码片段似乎相当于我:
var myArray = Array(); myArray['A'] = "Athens"; myArray['B'] = "Berlin";
和
var myObject = {'A': 'Athens', 'B':'Berlin'};
因为它们的行为都是一样的,还有typeof(myArray) == typeof(myObjects)
(都是typeof(myArray) == typeof(myObjects)
')。
这些变体有什么区别?
几乎所有的JavaScript都是一个对象,所以你可以通过设置任意属性来“滥用”一个Array对象。 这应该被认为是有害的 。 数组用于数字索引的数据 – 对于非数字键,使用Object。
下面是一个更具体的例子,为什么非数字键不能“适合”一个数组:
var myArray = Array(); myArray['A'] = "Athens"; myArray['B'] = "Berlin"; alert(myArray.length);
这不会显示“2”,而是“0” – 实际上,没有元素被添加到数组中,只是将一些新的属性添加到数组对象中。
在JS数组是对象,只是稍作修改(与几个更多的功能)。
功能如下:
concat every filer forEach join indexOf lastIndexOf map pop push reverse shift slice some sort splice toSource toString unshift valueOf
我认为,我对以前的回答太隐喻和含糊。 澄清如下。
Array,Boolean,Date,Function,Number,RegExp,String的一个实例是一个Object,但增强了每种类型特有的方法和属性。 例如,数组具有预定义的length
属性,而通用对象则不具有。
javascript:alert([].length+'\n'+{}.length)
显示器
0 未定义
本质上,FF Gecko解释器还区分数组和泛型对象,评估语言结构有着明显的区别。
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);
显示
一二三 [对象对象] [“一二三”] 4.toSource()忘了我! 3和我的长度! ({0:“1”,1:“2”,2:“3”,a:4))
和0 1 2 a
和0 1 2 a
。
关于所有对象都是函数的说法:
使用任意对象实例作为像123()
或"abc"()
或[]()
或{}()
或obj()
这样的Function
,在语法和语义上都不是,一个任意的对象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解释器低级内置原语(如Math
和JSON
和true
。
javascript:alert([Math, JSON, true.toSource()].join("\n\n"));
显示器
[object Math] [object JSON] (new Boolean(true))
在开发Javascript的时候,一种以对象为中心的编程风格(OOP的 – 面向对象的编程风格 – 这个“是我自己的双关语”)是流行的,并且这个解释器也被类似的命名为Java,使它更可信。 函数式编程技术被归入研究自动机,递归函数,形式语言等等的理论的更加抽象和深奥的考试,因此不如可口。 然而,这些正式考虑的优势在Javascript中明显体现出来,特别是在FF的Gecko引擎(即.toSource()
)中实现。
函数的Object定义特别令人满意,因为它被定义为递归关系! 定义使用它自己的定义!
function Function() { [native code] }
并且因为函数是一个对象,所以同样的情感是可行的
function Object() { [native code] }
。
大多数其他定义静默终端价值。 然而, eval()
是一个特别强大的基元,所以一个String也可以嵌入任意的功能。
再次注意,上面使用的白话模糊了对象类型和实例的区别。
JavaScript中的所有东西都是除原始类型之外的对象。
代码
var myArray = Array();
创建一个Array对象的实例
var myObject = {'A': 'Athens', 'B':'Berlin'};
创建一个Object对象的实例。
尝试下面的代码
alert(myArray.constructor) alert(myObject.constructor)
所以你会看到区别在于对象构造函数的类型。
Array对象的实例将包含Array原型的所有属性和方法。
一个实际的区别是JSON.stringify
在编码数组时将忽略所有的非数字索引:
var a = []; a['name'] = 'John'; JSON.stringify(a); // will output '[]'
而在使用对象的情况下:
var b = {}; b['name'] = 'John'; JSON.stringify(b); // will output '{"name":"John"}'
{}
-notation只是语法糖,使代码更好;-)
JavaScript有许多类似的构造,如函数的构造,其中function()只是一个同义词
var Func = new Function("<params>", "<code>");