var myArray = Array();
myArray['A'] = "Athens";
myArray['B'] = "Berlin";
和
var myObject = {'A': 'Athens', 'B':'Berlin'};
,因为它们都表现良好
这些变量之间是否有区别?
#1 楼
实际上,javascript中的所有内容都是对象,因此您可以通过在Array对象上设置任意属性来“滥用” Array对象。但是,这应该被认为是有害的。数组用于数字索引数据-对于非数字键,请使用对象。这是非数字键不能“适合”数组的一个更具体的示例:
var myArray = Array();
myArray['A'] = "Athens";
myArray['B'] = "Berlin";
alert(myArray.length);
它不会显示'2',但会显示'0'-实际上,没有将任何元素添加到数组,只是将一些新属性添加到了数组对象。
#2 楼
在JS数组中是对象,只是稍加修改(带有更多功能)。函数如:
concat
every
filer
forEach
join
indexOf
lastIndexOf
map
pop
push
reverse
shift
slice
some
sort
splice
toSource
toString
unshift
valueOf
评论
尽管我认为列出的所有功能并不是每个JS实现都内置的,但您已经明白了。另一个区别是原型不同(这些额外功能暗示)。
– Rashack
09年5月17日在9:26
#3 楼
我认为,我对先前的答案也隐喻和含糊。澄清如下。Array,Boolean,Date,Function,Number,RegExp,String的实例是一个对象,但通过每种类型的方法和属性进行了增强。例如,数组具有预定义的
length
属性,而普通对象则没有。javascript:alert([].length+'\n'+{}.length)
displays
0 undefined
本质上,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);
显示
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 a
和0 1 2 a
。关于所有对象都是函数的声明:
在语法上和语义上将任意对象实例用作
123()
或"abc"()
或[]()
或{}()
或obj()
之类的函数,其中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
定义,因此声明所有对象都是函数! (开玩笑的是,我故意模糊和模糊了对象实例与它的类型之间的区别!不过,这表明“没有另一个就不能拥有一个”,对象和功能!大写强调类型为功能和对象范例似乎都是JS解释器底层内置原语(例如
Math
和JSON
和true
)的编程和实现的基础。 > javascript:alert([Math, JSON, true.toSource()].join("\n\n"));
[object Math]
[object JSON]
(new Boolean(true))
在开发Javascript时,以对象为中心的编程风格(OOP的-面向对象的编程风格-“ s”是我自己的双关语)正在流行,并且类似的解释器也用Java命名,以提高其可信度。 。函数式编程技术被归类到更抽象和深奥的考试中,这些考试研究自动机,递归函数,形式语言等的理论,并且这些都不是可口的。但是,这些正式考虑的优点在Javascript中已明显体现出来,尤其是在FF的Gecko引擎(即
.toSource()
)中实现的情况。Function的Object定义特别令人满意作为复发关系!使用它自己的定义来定义!
function Function() { [native code] }
,由于函数是一个对象,因此对
function Object() { [native code] }
的看法相同。其他大多数定义都静默化为静态。终值。但是,
eval()
是一个特别强大的原语,因此String也可以嵌入任意功能。再次注意,上面使用的白话语掩盖了对象类型和实例的区别。#4 楼
JavaScript中的所有内容都是除原始类型以外的对象。代码
var myArray = Array();
创建Array对象的实例,而
var myObject = {'A': 'Athens', 'B':'Berlin'};
创建Object对象的实例。
尝试以下代码
alert(myArray.constructor)
alert(myObject.constructor)
所以您将看到区别在于对象构造函数的类型。
Array对象的实例将包含Array原型的所有属性和方法。
#5 楼
您可以将命名属性添加到javascript中的几乎所有内容中,但这并不意味着您应该这样做。如果要关联数组,请使用
Array
代替javascript中的Object
。请注意,如果您真的想使用带有命名属性的
Array
而不是Object
,则这些属性将无法在for...of
循环中访问,并且在对其进行JSON编码进行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"}
#6 楼
数组与JavaScript中其他对象之间的区别。虽然数组具有神奇的更新长度属性,但是对于除数组之外的其他对象,则无法实现该属性。
var arrName = [];
arrName[5] = "test";
arrName.length; // <- 6
数组用于存储具有序索引的事物-像传统数组,堆栈或队列一样使用它。对象是哈希-将其用于具有唯一键的数据。
#7 楼
在JavaScript中,数组是特殊类型的对象typeof new Array(); // returns "object"
typeof new Object(); // returns "object
数组使用编号索引,而对象使用名为Indexes
,因此我们可以将命名属性添加到Array
const arr = []
arr["A"] = "Hello" //["A":"Hello"]
console.log(arr.length) // 0
arr.length返回0,因为具有命名索引的数组更喜欢调用Objects
console.log(Object.keys(clothing)); // ["A"]
console.log(Object.keys(clothing).length); //1
#8 楼
{}
-表示法只是语法上的糖,使代码更美观;-) JavaScript具有许多类似的构造,例如函数的构造,其中function()只是
var Func = new Function("<params>", "<code>");
评论
函数构造函数不是函数文字的同义词。当构造函数是全局的时,字面量在词法范围内。 {}是文字对象表示法,[]是文字数组,我不确定您的答案是什么。
–胡安·门德斯(Juan Mendes)
2011年4月21日在17:11
同样,声明的函数在执行任何代码之前可用,使用Function构造函数的赋值在创建它们的代码执行之前不可用。
–RobG
2014年9月11日下午2:52
评论
myArray.length返回数组中最后一个元素的数字索引/键,但不返回元素的实际数量。 Array对象的属性与数组值不同吗?
– Dasha Salo
09年5月17日在9:50
我只是想说明一下,如果您将Array对象当作常规对象对待,它的预期语义就会被滥用。链接的文章虽然做得更好:)
– Paul Dixon
09年5月17日上午10:19
下次有人说JavaScript是一种很好的开发语言时,我将向他展示此示例。谢谢。
–奥利维尔·庞斯(Olivier Pons)
2014年4月19日在8:04
@Olivier,您所说的“ bug”也可以是一个很棒的“功能”。您可以向数组添加标题和描述,而不会影响它们的内容或长度,也不必将它们包装在具有标题,描述和项目属性的对象中。这完全取决于您对语言的了解程度和使用方式。
– tao
3月9日8:27
在数组上使用自定义属性并不是天生的错误。出问题的是,一旦他们期望它们充当阵列成员。它们是数组属性,而不是成员,因此不受数组方法的影响。这实际上是上述链接文章的作者在评论中说的。现在,公平地说,我不建议这样做,因为它可能会使使用您的代码的人感到困惑。或者,如果它们才刚刚开始,它将以身作则,使他们走上危险的道路。但是我不会说JavaScript不好,因为JavaScript允许大多数您不希望的东西。
– tao
3月9日8:54