Почему я не могу добавить свойства к строковому объекту в javascript?


я унаследовал некоторый код javascript, написанный другим разработчиком. Ему не понравился компонент сетки, который мы использовали на протяжении всего проекта, поэтому он решил написать свой собственный. Сетка, которую он написал, не может сортировать даты, потому что она может привязываться только к строкам / числам. Он преобразует все даты в строки перед их использованием. Я посмотрел на строковое форматирование функции даты, которую он написал, и решил, что я могу просто добавить свойство даты в строку с исходным значением, а затем при сортировке посмотреть, есть ли в строке дата свойство и сортировка на основе этого. Однако, похоже, вы не можете добавить свойства к строкам в javascript. Я не знал, что есть определенные типы, к которым вы не можете добавить свойства. Например:

<html>
<script>
var test = "test";
test.test = "test inner";
console.log(test);
console.log(test.test);
</script>
2 51

2 ответа:

в JavaScript есть 6 типов языков:

  • 5 примитивных типов: строка,, Boolean, Null, Undefined
  • 1 непримитивный тип:объект

значения примитивных типов называются примитивными значениями и не могут иметь свойств.
Значения объект называются непримитивные типы объекты могут иметь свойства.

при попытке присвоить свойство с именем 'bar' переменной foo, например:

foo.bar = 'abc';

тогда результат будет зависеть от типа значения foo:

(a), если значение foo типа Undefined или Null, тогда будет выдана ошибка,

(b), если значение foo это типа объект, затем именованное свойство 'bar' будет определен на объекте foo (при необходимости), и его значение будет установлено значение 'abc',

(c), если значение foo типа ,строка или Boolean, то переменная foo не будет изменено в любом случае. В этом случае приведенная выше операция присваивания будет Нооп.

Итак, как вы видите, назначение свойств переменным имеет смысл только в том случае, если эти переменные являются объектами. Если это не так, то назначение либо вообще ничего не сделает, либо даже выдаст ошибку.


в вашем случае, переменной test содержит значение типа строка, вот так:

test.test = "test inner";

вообще ничего не делает.


однако, поскольку ES5 представил свойства доступа, есть исключение из того, что я сказал выше. Свойства метода доступа позволяют нам определять функции, которые вызываются всякий раз, когда свойство извлекается или устанавливается.

например:

var str = '';
str.prop;

здесь str является переменной, содержащей a строка значение. Поэтому доступ к свойству этой переменной должен быть no-op (str.prop просто возвращает undefined). Это верно за одним исключением: если String.prototype содержит свойство доступа 'prop' С ОПРЕДЕЛЕННЫМ геттером, то этот геттер будет вызванный.

Итак, если это определено:

Object.defineProperty( String.prototype, 'prop', {
    get: function () {
        // this function is the getter
    }
}); 

после этого

str.prop;

вызовет эту функцию геттера.

Live demo: http://jsfiddle.net/fmNgu/

однако я не думаю, что добавление свойств доступа к встроенным прототипам было бы хорошей практикой.

Если вы используете строковый объект, вы можете добавить свойства:

var test = new String("test");
test.test = "test inner";
console.log(test.toString()); // prints out "test"
console.log(test.test); // prints out "test inner"