为什么我可以将命名属性添加到数组中,就像它是一个对象一样?

时间:2009-05-17 09:11:30

标签: javascript arrays object javascript-objects

以下两个不同的代码片段似乎与我相同:

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

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

因为它们的行为相同,而且typeof(myArray) == typeof(myObjects)(都产生'对象')。

这些变体之间有什么区别吗?

8 个答案:

答案 0 :(得分:127)

几乎javascript中的所有内容都是一个对象,因此您可以通过在其上设置任意属性来“滥用”Array对象。这个should be considered harmful虽然。数组用于数字索引数据 - 对于非数字键,使用Object。

这是一个更具体的例子,说明为什么非数字键不适合“数组”:

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

alert(myArray.length);

这不显示'2',而是'0' - 实际上,没有元素添加到数组中,只是添加了一些新属性到数组对象。

答案 1 :(得分:14)

在JS数组中是对象,只是略微修改(带有更多函数)。

功能如:

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

答案 2 :(得分:6)

我认为,我以前的回答过于隐喻和含糊不清。澄清如下。

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

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

显示器

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()等函数在语法和语义上都不正确objFunction以外的任何类型,因此任意对象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解释器低级内置基元的基础,例如MathJSON以及true。< / p>

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

显示器

[object Math]

[object JSON]

(new Boolean(true))

在Javascript开发的时候,一种以对象为中心的编程风格(面向对象的编程风格 - “s”是我自己的双关语!)很流行,并且解释器同样用Java命名为它的可信度更高。功能编程技术被降级为更抽象和深奥的考试,研究自动机,递归函数,形式语言等的理论,因此不适合。然而,这些正式考虑因素的优势在Javascript中明显体现出来,特别是在FF的Gecko引擎中实现(即.toSource())。


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

function Function() { [native code] }
并且由于函数是一个对象,因此相同的情绪成立 function Object() { [native code] }

大多数其他定义停顿在静态终端值上。但是,eval()是一个特别强大的原语,因此String也可以嵌入任意功能。

再次注意,上面使用的白话掩盖了对象类型和实例区别。

答案 3 :(得分:5)

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

代码

var myArray = Array();

时创建Array对象的实例
var myObject = {'A': 'Athens', 'B':'Berlin'};

创建一个Object对象的实例。

尝试以下代码

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

所以你会看到区别在于对象构造函数的类型。

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

答案 4 :(得分:1)

一个实际的区别是,在JSON.stringify上使用array时,所有非数字索引都会被忽略:

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"}

答案 5 :(得分:1)

  

JavaScript中的数组和其他对象之间的区别。虽然数组具有神奇的更新长度属性,但对于除数组之外的对象,无法实现此类属性。

var arrName = [];
arrName[5] = "test";
arrName.length; // <- 6
  

数组用于存储带有序数索引的东西 - 像传统的数组,堆栈或队列一样使用它。对象是哈希 - 将其用于具有不同密钥的数据。

答案 6 :(得分:1)

在JavaScript中,数组是特殊类型的对象

0 % colors.length = 0
1 % colors.length = 1
2 % colors.length = 2
3 % colors.length = 0
4 % colors.length = 1
etc..

使用编号索引的数组,使用编号索引的对象

因此我们可以将命名属性添加到Array

typeof new Array(); // returns "object" 
typeof new Object(); // returns "object

arr.length返回0,因为具有命名索引的数组更喜欢调用对象

const arr = []
arr["A"] = "Hello" //["A":"Hello"]

console.log(arr.length) // 0 

答案 7 :(得分:-1)

{} - 符号只是使语法更好的语法糖; - )

JavaScript有许多类似的结构,比如函数的构造,其中function()只是

的同义词
var Func = new Function("<params>", "<code>");