Почему я не могу установить свойства элемента массива (строки) в JavaScript? - PullRequest
6 голосов
/ 28 мая 2011
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

Почему этот код не работает должным образом?

Ответы [ 6 ]

10 голосов
/ 28 мая 2011

Массив не имеет значения - вы пытаетесь установить свойство для примитива :

данных, которые не являются объектом инет никаких методов.JavaScript имеет 5 примитивных типов данных : строка , число , логическое значение , ноль , undefined .За исключением значений 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]
3 голосов
/ 28 мая 2011

Ваши элементы массива являются строковыми литералами .В JavaScript создается впечатление, что строковые литералы являются объектами и имеют свойства, но на самом деле, когда вы делаете array[0].property, JavaScript создает временный объект для вашей строки и присваивает этому свойству свойство.

Вот почемусреднее оповещение работает правильно, а остальные нет.Если вы объявите свой массив как:

var array = [new String('a'), new String('b'), new String('c')];

, все три будут работать.

2 голосов
/ 28 мая 2011

Это связано с причудой (или ограничением производительности) в 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) оказывается значением true-y.

Счастливого кодирования.


* Это сломает множество библиотек, которые делают typeof x === "string"

2 голосов
/ 28 мая 2011

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);   
1 голос
/ 28 мая 2011

Вы пытаетесь сделать 'a'.property = 'something'.

Я не знаю ни одного языка, который позволял бы вам присваивать свойство строки;

, что было бы похоже на выполнение 12.property = 'something'.

0 голосов
/ 28 мая 2011

В строках js и простых типах, хранящихся / возвращаемых по значению, а не по ссылке.

Если в вашем массиве есть какой-то объект, он будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...