var array = ['a', 'b', 'c'];
array[0].property = 'value';
alert(array[0].property);
alert(array[0].property = 'value');
alert(array[0].property);
结果呢? undefined
,'value'
,然后是undefined
为什么这段代码没有按预期工作?
答案 0 :(得分:10)
数组无关紧要 - 您正试图在primitive上设置属性:
不是对象的数据并且确实如此 没有任何方法。 JavaScript有5个 原始数据类型:字符串,数字, 布尔, null ,未定义。随着 所有都是null和undefined的异常 原始值具有对象 围绕着包裹的等价物 原始值,例如一个String对象 包裹字符串原语。所有 原语是不可变的。
如果你绝对必须使用一个属性来在字符串中携带这些附加信息,那么另一种方法是使用等价的对象:
>>> var array = [new String('a'), new String('b'), new String('c')];
>>> array[0].property
undefined
>>> array[0].property = 'value'
"value"
>>> array[0].property
"value"
如果你这样做可能需要注意,以后需要检测该值是否为字符串:
>>> var a = ['s', new String('s')];
>>> a.map(function(s) { return typeof s; });
["string", "object"]
>>> a.map(function(s) { return s instanceof String });
[false, true]
>>> a.map(function(s) { return Object.prototype.toString.call(s) == '[object String]' });
[true, true]
答案 1 :(得分:3)
您的数组元素是字符串 literals 。 JavaScript使得它看起来像字符串文字是对象并具有属性,但是当您执行array[0].property
时实际发生的是JavaScript正在为您的字符串创建临时对象并将属性分配给它。
这就是为什么中间警报正常工作而其他警报没有正常工作的原因。如果您将数组声明为:
var array = [new String('a'), new String('b'), new String('c')];
这三个都有用。
答案 2 :(得分:2)
array[0]
是一个字符串,即您在第一行中设置的'a'
,而JavaScript字符串中不能包含其他属性。
如果要使用属性,则必须使用对象,例如简单的“空”对象:new Object()
或短{}
:
var array = [{}];
array[0].property = 'value';
alert(array[0].property);
alert(array[0].property = 'value');
alert(array[0].property);
答案 3 :(得分:2)
这是由于JavaScript中的怪癖(或性能限制) - 原语类型string
,boolean
和number
是不可变的和任何属性赋值只会“消失”(单居民原始类型undefined
和null
将在尝试的属性赋值上抛出异常)。这是因为这些原始值是不是真实对象(它使它们在运行时更加轻量级)。
但是,对于每种基本类型,都有一个包装类型:String
,Boolean
和Number
。包装器类型是真实的对象,可以分配自定义属性。
虽然我不会这样做,但这会起作用(听起来像是“icky设计”):
var s = new String("foo");
s.bar = "hello"
alert(s.bar)
然而,这引入了许多奇怪的怪癖 - typeof ""
是“字符串”而typeof s
是“对象”*,而"" instanceof String
是假的{{1 }} 是真的。此外,s instanceof String
恰好是真值y。
快乐的编码。
*这将打破许多执行new Boolean(false)
答案 4 :(得分:1)
您正在尝试'a'.property = 'something'
。
我不知道任何语言允许您指定字符串的属性;
就像做12.property = 'something'
。
答案 5 :(得分:0)
在js字符串和由value存储/返回的简单类型中,而不是通过引用。
如果你的数组中有一些对象,那么它就可以了。