var array = ['a', 'b', 'c'];
array[0].property = 'value';
a开发者_Python百科lert(array[0].property);
alert(array[0].property = 'value');
alert(array[0].property);
The result? undefined
, 'value'
, then undefined
Why isn't this code working as expected?
The Array is irrelevant - you're trying to set a property on a primitive:
A data that is not an object and does not have any methods. JavaScript has 5 primitive datatypes: string, number, boolean, null, undefined. With the exception of null and undefined, all primitives values have object equivalents which wrap around the primitive values, e.g. a String object wraps around a string primitive. All primitives are immutable.
If you absolutely must use a property to carry this additional information around in a string, an alternative would be to use the object equivalent:
>>> var array = [new String('a'), new String('b'), new String('c')];
>>> array[0].property
undefined
>>> array[0].property = 'value'
"value"
>>> array[0].property
"value"
A potential gotcha to look out for if you do this and later need to detect that the value is a string:
>>> 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]
Your array elements are string literals. JavaScript makes it seem like string literals are objects and have properties, but what's actually happening when you do array[0].property
is that JavaScript is creating a temporary object for your string and assigning the property to that.
That's why the middle alert works correctly and the others don't. If you declared your array like:
var array = [new String('a'), new String('b'), new String('c')];
all three would work.
array[0]
is a string, namely 'a'
which you set in the first line and in JavaScript strings can't have additional properties.
If you want to use properties you have to use an object, for example a simple "empty" object: new Object()
or short {}
:
var array = [{}];
array[0].property = 'value';
alert(array[0].property);
alert(array[0].property = 'value');
alert(array[0].property);
This is due to a quirk (or performance restriction) in JavaScript -- the primitive types string
, boolean
, and number
are immutable and any property assignment will just "vanish" (the single-inhabitant primitive types undefined
and null
will throw an exception on attempted property assignment). This is because these primitive values are not real objects (it makes them much more lightweight for the run-time).
However, for each of the primitive types there is a wrapper type: String
, Boolean
, and Number
, respectively. The wrapper types are real objects and can have custom properties assigned.
While I would not do this, this will work (it sounds like an "icky design"):
var s = new String("foo");
s.bar = "hello"
alert(s.bar)
However, there are a number of odd quirks that this introduces -- typeof ""
is "string" while typeof s
is "object"*, and "" instanceof String
is false while s instanceof String
is true. Also, new Boolean(false)
happens to be a truth-y value.
Happy coding.
*This will break a number of noddy library that do typeof x === "string"
You are trying to do 'a'.property = 'something'
.
I'm not aware of any language that lets you assign a property of a string;
that would be like doing 12.property = 'something'
.
In js strings and simple types stored/returned by value, not by reference.
If in your array you have some object, then it will work.
精彩评论