我不应该这样向数组添加元素:

var b   = [];
b.val_1 = "a";
b.val_2 = "b";
b.val_3 = "c";

我不能使用本机数组方法,为什么不能仅使用对象。我只是将属性添加到数组,而不是元素。我想这使它们与length属性平行。虽然尝试重置长度(b.length = "a string")会得到Uncaught RangeError: Invalid array length

无论如何,我仍然可以看到设置的属性:
console.log(b); //[val_1: "a", val_2: "b", val_3: "c"]

我可以使用点语法来访问它:
console.log(b.val_1); //a

如果数组只是对象,就像字符串或数字是对象一样,为什么不能(不是我想要的)使用以下语法将属性附加到它们:
var num    = 1;
num.prop_1 = "a string";

console.log(num); //1

我无法使用点语法访问其属性
console.log(num.prp); //undefined

为什么可以使用数组而不是其他数据类型来完成此操作。对于所有情况,我都应该使用{},并且只需要使用{},那么为什么数组具有此功能呢?

JSBIN

最佳答案

由于语言将数组视为对象,因此您可以通过键入以下代码行来查看此内容:

console.log(typeof []) // object

但是其他类型(例如数字文字,字符串文字NaN ...等)是原始类型,并且仅在语言定义的某些上下文中包装在它们的对象表示中。

如果要向这样的数字添加属性或方法,则可以使用Number构造函数,如下所示:
var num = new Number(1);
num.prop_1 = "fdadsf";
console.log(num.prop_1);

使用Number构造函数返回一个数字对象,您可以通过键入以下行来看到它:
console.log(typeof num); // object

在第一种情况下:
var num = 1;
console.log(typeof num) // number

编辑2:例如,当您在数字文字或字符串文字上调用方法时,该原语将通过发生方法调用的语言自动包装到其对象表示中,例如:
var num = 3;
console.log(num.toFixed(3)); // 3.000

这里num是一个原始变量,但是当您在其上调用toFixed() metohd时,它将被包装到Number对象中,因此可以进行方法调用。

编辑:在第一种情况下,您创建了一个类似于第一个var str = new String()的字符串,但是随后将其更改为str = "asdf",然后分配了属性str.var_1 = "1234"

当然,这是行不通的,因为当您分配str = "asdf"时,str成为原始类型,并且原来创建的Object实例现在不存在了,并且您无法向原始添加属性。

在第二个中,它没有像您说的那样输出undefined,我在Firebug中对其进行了测试,并且一切正常。

编辑3:



这取自MDN Documentation,当您使用像var p = String(3)这样的字符串时,它将成为转换函数而不是构造函数,并且它会返回一个原始字符串,如您在上面的引文中所见。

关于您的第二条评论,我不明白我的评论是如何被反抗的,因为如果您尝试console.log(p.pr),则会得到undefined,这表明p是原始类型而不是对象。

09-26 19:31
查看更多