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
爲什麼我不能在JavaScript中設置數組元素(字符串)的屬性?
爲什麼不按預期工作?
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
爲什麼我不能在JavaScript中設置數組元素(字符串)的屬性?
爲什麼不按預期工作?
的陣列是無關緊要的 - 你想設置一個primitive屬性:
的數據不是一個對象並沒有 沒有任何方法。 JavaScript有5個 原始數據類型:串,數, 布爾,空,不確定。由於空和未定義的例外情況,所有的基元值都具有對象 等價物,其中圍繞 原始值(例如,0)包圍。一個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]
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);
廢話。我從來不知道這一點。看來數字也不能具有其他屬性。謝謝! – ClosureCowboy 2011-05-28 18:24:19
反對的任何理由? – RoToRa 2011-05-29 14:39:06
我想知道同樣的事情。你對我有好感。 – ClosureCowboy 2011-05-30 19:53:19
你正在嘗試做'a'.property = 'something'
。
我不知道任何語言可以讓你指定一個字符串的屬性;
那就好像在做12.property = 'something'
。
但是,您可以將屬性分配給字符串的* prototype *。你可以寫'String.prototype.property ='something'',這將使所有的字符串都有一個property屬性,其值爲something。包括''''。屬性'。 – rid 2011-05-28 18:30:00
@rdineiu啊的確如此,我一直使用''string'.contains('substring')'。然而,他似乎想做'a'.prop = 1; 「b'.prop = 2; ...';至少這是代碼隱含的。不過很遺憾的是,由於語言和庫問題,修改Array.prototype和Object.prototype是危險的,所以這些特性的使用比他們應該少。 – ninjagecko 2011-05-28 18:57:32
你的數組元素是字符串文字。 JavaScript使得它看起來像字符串文字是對象並且具有屬性,但是當你做時,實際發生的事情是JavaScript爲你的字符串創建一個臨時對象並將屬性賦值給它。
這就是爲什麼中間警報正常工作而其他人不正確。如果你宣佈你的陣列是這樣的:
var array = [new String('a'), new String('b'), new String('c')];
所有三個工作。
這是由於在JavaScript中的異常行爲(或性能的限制) - 該原始類型string
,boolean
和number
是不變和任何財產分配將只是「消失」(單居民基本類型undefined
和null
將在試圖分配屬性時引發異常)。這是因爲這些原始值是而不是真實對象(它使得它們在運行時更加輕量級)。
然而,用於每個原語類型的有一個包裝類型:分別String
,Boolean
,和Number
。包裝類型爲real對象,並且可以分配自定義屬性。
雖然我不會這麼做,這將工作(這聽起來像一個「噁心設計」):
var s = new String("foo");
s.bar = "hello"
alert(s.bar)
然而,也有一些奇怪的怪癖,這一介紹 - typeof ""
是「字符串」,而typeof s
是「對象」*,並且"" instanceof String
爲假,而s instanceof String
爲真。此外,new Boolean(false)
恰好是一個真值。
快樂編碼。
*這將打破一些諾迪庫是做typeof x === "string"
在JS字符串和簡單類型存儲/通過返回值,而不是引用。
如果在你的數組中有一些對象,那麼它將工作。
儘管問題的確與'字符串值的屬性有關,但沒有「值」與vs JavaScript中的「引用」區別。 – 2011-05-28 18:55:44
@pst,除了基元以外的所有東西總是在JS中引用。原始材料 - 按價值。 – gaRex 2011-05-28 19:02:06
JavaScript中的所有值都是「按值」或「只是它們自己」;也就是說,一個對象的值本身就是 - *沒有引用*。 (實現可以在內部使用引用*;這個細節不會泄露)。所有原始值恰好是*完全不可變的。* Java *引入了「引用類型」的區別; JavaScript沒有這種區別,調用語義完全由[Call By Object Sharing](http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing)描述,無需引入來自不同語言的「引用」。 – 2011-05-29 19:01:58
另一個問題:'[new String('a')]。indexOf('a')=== -1' – OrangeDog 2013-03-27 14:45:49