Javascript同时创建对象和数组

Javascript同时创建对象和数组,javascript,arrays,object,overlap,Javascript,Arrays,Object,Overlap,为什么javascript允许我执行以下操作 a = {two : 'World'}; a[1] = 'Hello'; console.log(a[1]); console.log(a.two); 输出是 Hello World wow 它不应该抱怨我试图使用对象作为数组吗?顺便说一下,这对任何东西都有效,就像这样 b = new Date(); b[1] = 'Wow'; console.log(b[1]); 输出是 Hello World wow 这个有用吗?在我看来,这似乎是一

为什么javascript允许我执行以下操作

a = {two : 'World'};
a[1] = 'Hello';
console.log(a[1]);
console.log(a.two);
输出是

Hello
World
wow
它不应该抱怨我试图使用对象作为数组吗?顺便说一下,这对任何东西都有效,就像这样

b = new Date();
b[1] = 'Wow';
console.log(b[1]);
输出是

Hello
World
wow
这个有用吗?在我看来,这似乎是一个糟糕的编程实践

它不应该抱怨我试图使用对象作为数组吗

不允许。允许使用数字属性。方括号符号
[]
用于非有效javascript标识符的键的对象。不仅仅是在阵列上

a[ "some-invalid***identifier" ] = 'some value';
顺便说一下,这对任何东西都有效,就像这样

b = new Date();
b[1] = 'Wow';
console.log(b[1]);

是的,同样的原因
new Date()
返回一个对象,可以通过点括号或方括号表示法将属性指定给该对象。

您不是将对象视为数组,而是在对象中使用数字键。正如这两者都是有效的:

var o = { "test":1 };
o["test2"] = 2;
这些也是:

var o = { 1: "test" };
o[2] = "test2";
Edit:正如下面的评论所指出的,上面的语法实际上是误导性的,因为
1
在这两种情况下都被转换为字符串-所以从技术上讲,这与

var o = { "1": "test" };
正如你在这里看到的:

var o = {1:"test"};
for (i in o) console.log(i, i===1, i==="1"); // 1 false true
因为访问对象属性的[key]符号将接受任何作为键的内容,包括数字。您可以使用的其他东西包括: 变量a={},b={}; a{b}=1;//对象a的属性是对象“b”。 它提供了一个真正统一的对象模型,而不是糟糕的编程实践。


请参阅注释。

在Javascript中,所有数组都是对象。两者之间没有明确的分界线。数组具有某些属性和方法,但作为对象实现

语法
[1]
是两种等价的Javascript之一。这两个是等效的:

var foo = {};
foo.bar = 'foobar';
foo['bar'] = 'foobar';
但是,使用点符号(
foo.bar
),您只能访问有效Javascript标识符的属性。这意味着:

字母数字字符序列,也包括下划线(“”)和美元符号($”),不能以数字()


您可以用这种方式设置任何Javascript对象的属性——数组、对象、日期对象、字符串、数字,因为它们都来自相同的对象类型。

老实说,我认为控制台的输出非常有启发性:

var a = {two: "World"};
a[1] = "Hello";
console.log(a);
//   1: "Hello"
//   two: "World"
// > __proto__: Object

var b = new Date();
b[1] = 'Wow';
console.dir(b[1]); // console.log just returns the timestamp
//   1: "Wow"
// v __proto__: Date
//   > constructor: function Date() { [native code] }
//   > getDate: ...
如您所见,这两个都只是对象,一个继承自泛型对象,另一个继承自日期。与任何其他对象一样,可以为它们分配一个键/值对,其中1刚刚被转换为字符串


如果你这样使用的话,它无疑是一个混乱的编码,但它是JavaScript原理的一个非常重要的说明。有很多有用的方法可以扩展在语法上与您正在做的事情相似的对象。

小小的更正,从技术上讲是
{'1':'test'}
--所有对象键都是stringsGood point-相应地编辑。奇怪的是,这似乎也适用于数组-对数组键的相同测试也会返回
1 false-true
。这是因为数组是如何实现的。在现代浏览器中运行此命令以了解我的意思:
varx={'0':'a','1':'B','2':'C'};defineProperty(x,'length',{value:3,writable:true,configurable:true});x、 _uuuproto_uuuu=Array.prototype
x
现在是一个数组。在这个上下文中,前两行很容易混淆。是的,所有数组都是对象,但这与这个答案无关:)这么多好的答案,我不知道该选择哪个。Thanx伙计们。我现在看到javascript没有像C中的连续内存分配那样的真正数组。@cwolves所有数组都是对象,并且所有对象都可以在其上指定任意属性。是的,但问题是关于另一个方向,关于为什么对象像数组。@cwolves对象像数组,因为数组像对象,因为数组是对象…不完全正确。键只能是字符串,但JavaScript会将任何内容转换为字符串;a[b]=1;a[a]=1;a[{}]=1;//a=={'[object]':1}}--它不是将对象“b”指定为键,而是将“[object object]”指定为键。我更喜欢将列表/数组与属性分开。我被难住了,为什么我的代码中没有
x=newarray()
调用,但是
x[I]=123
仍然有效。我只是不明白为什么他们不能为对象属性使用不同的符号,比如
array[0]=“first entry”
property{x}='property eks'
@cwolves,我同意并将删除我的解决方案,但这里的注释中表达了非常有说服力的见解,一切都是一个对象,所以你几乎可以使用任何东西作为对象-数组、日期等。但是,无论普通对象(即由对象构造函数创建的对象)在什么地方工作,使用数组、日期都被认为是不好的做法。@RobG我很困惑,我想你是在说这样构造一个对象是不好的,
x=newobject()
,而不是这样的
x=newarray()
puk-我很困惑!:-)我的观点是,数组只能在需要数组的特殊属性(例如,对索引属性的有序访问)的情况下使用。如果只需要名称/值对的一般存储,则应使用普通对象。另外,通常认为使用文本更好:
var x=[]
var y={}
但结果与使用
var x=new Object()
var y=new Array()
@RobG相同,我更喜欢文本,因为它们更容易理解,更紧凑。但javascript将对象和数组视为同一事物,这仍然让我大吃一惊。Python有对象、列表和字典,它们有点像JS数组,但它们在对象(类实例)和列表/字典之间是一条清晰的界线。我是C/Python的家伙,所以不要搞乱数组/列表