以下两个不同的代码片段对我来说似乎是等价的:
var myArray = Array();
myArray['A'] = "Athens";
myArray['B'] = "Berlin";
和
var myObject = {'A': 'Athens', 'B':'Berlin'};
因为它们的行为相同,而且typeof(myArray) == typeof(myObjects)
(都产生“对象”)。
这些变体之间有什么区别吗?
以下两个不同的代码片段对我来说似乎是等价的:
var myArray = Array();
myArray['A'] = "Athens";
myArray['B'] = "Berlin";
和
var myObject = {'A': 'Athens', 'B':'Berlin'};
因为它们的行为相同,而且typeof(myArray) == typeof(myObjects)
(都产生“对象”)。
这些变体之间有什么区别吗?
在 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 的实例是一个对象,但增强了特定于每种类型的方法和属性。例如,数组具有预定义的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:"二", 2:"三", a:4})
和0 1 2 a
和0 1 2 a
。
关于所有对象都是函数的说法:
将任意对象实例用作函数,例如123()
or"abc"()
或[]()
or{}()
或obj()
whereobj
是除 之外的任何类型Function
,在语法和语义上都不正确,因此任意对象 INSTANCE 不是 a Function
。但是,给定一个对象obj
并且它的类型为 as Array, Boolean, Date, ...
,如何obj
变成 as 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
定义,因此声明所有对象都是函数!(诙谐的是我故意模糊和模糊了对象实例与其类型的区别!不过,这表明“你不能没有另一个”,对象和功能!大写强调类型为反对实例。)
函数范式和对象范式似乎都是 JS 解释器低级内置原语(例如Math
andJSON
和 )的编程和实现的基础true
。
javascript:alert([Math, JSON, true.toSource()].join("\n\n"));
显示
[object Math]
[object JSON]
(new Boolean(true))
在开发 Javascript 的时候,以对象为中心的编程风格(OOP's - 面向对象的编程风格 - “'s”是我自己的双关语!)正在流行,解释器同样被命名为 Java 以赋予它更大的可信度. 函数式编程技术被归为更抽象和深奥的考试,研究自动机、递归函数、形式语言等的理论,因此不那么令人愉快。然而,这些形式考虑的优势在 Javascript 中很明显,特别是在 FF 的 Gecko 引擎(即.toSource()
)中实现的。
Function 的 Object 定义特别令人满意,因为它被定义为递推关系!使用它自己的定义来定义!
function Function() { [native code] }
并且由于一个函数是一个对象,所以同样的情绪也适用于
function Object() { [native code] }
。
大多数其他定义都停止为静态终端值。然而,eval()
是一个特别强大的原语,因此字符串也可以嵌入任意功能。
再次注意,上面使用的白话掩盖了对象类型和实例的区别。
JavaScript 中的所有内容都是除基本类型之外的对象。
代码
var myArray = Array();
创建 Array 对象的实例,而
var myObject = {'A': 'Athens', 'B':'Berlin'};
创建一个 Object 对象的实例。
试试下面的代码
alert(myArray.constructor)
alert(myObject.constructor)
所以你会看到不同之处在于对象构造函数的类型。
Array 对象的实例将包含 Array 原型的所有属性和方法。
您可以将命名属性添加到 JavaScript 中的几乎所有内容,但这并不意味着您应该这样做。
Array
在 javascript 中应该用作列表,如果你想要一个关联数组,请使用Object
。
请注意,如果您真的想使用Array
具有命名属性的属性而不是Object
那些属性,则这些属性将无法在for...of
循环中访问,并且当 JSON 编码它以传递它时,您也可能会得到意想不到的结果。请参阅下面的示例,其中所有非数字索引都被忽略:
let arr = [];
let 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 [] <- not what you expected
JSON.stringify(obj); // will return {"name":"John"}