Динамические переменные JavaScript
С помощью этого сценария я добавляю переменные к объекту во время выполнения:
function MyDocument(someDocument)
{
if(!(someDocument instanceof KnownDocumentClass))
throw "Object must be an instance of KnownDocumentClass: " + someDocument;
this.Document = someDocument;
this.Fields = {};
this.updateValues = function()
{
for (var _it = this.Document.iterator(); _it.hasNext();)
{
var _property = _it.next();
try
{
this[_property.getQualifiedName()] = _property.getContent();
}
catch(err)
{
log("Error :"+err);
}
}
}
this.updateValues();
}
Так, например, я могу использовать
var mydoc = new MyDocument(knownjavadoc);
log(mydoc.Creator) // Shows the original content.
Этот контент может иметь несколько типов (некоторые int
, немного String
и много других пользовательских классов Java). Так что может случиться так, что log(mydoc.SomeProperty)
возвращает:
PropertyObjectImpl[id=abc123, data=Some Data, type=Node, order=42]
Я знаю, что я мог бы добавить функцию MyDocument
лайк
this.getValueAsString = function(name)
{
var _prop = this[name];
if(_prop instanceof PropertyObjectImpl)
return "PropertyObject with ID : " + _prop.getID();
else
return _prop;
}
Но для целей тренировки я хочу добавить эту функцию как toValueString()
непосредственно на эти свойства, так что вызов, как:
var value = mydoc.SomeProperty.toValueString()
вместо
var value = mydoc.getValueAsString("SomeProperty");
Это возможно?
2 ответа
Вы можете просто переопределить .toString()
реализация для рассматриваемых типов, а не реализация чего-то, что, вероятно, будет делать то же самое.
Переопределение .toString()
на существующих типах
Number.prototype.toString = function() {
// return .toString() logic for Number types
}
Boolean.prototype.toString = function() {
// return .toString() logic for Number types
}
Переопределение .toString()
на заказной тип
var CustomType = (function() {
function CustomType() {
// CustomType logic
}
CustomType.prototype.toString = function() {
// return .toString() logic for CustomType
}
return CustomType;
})();
Помните, toString()
встроен в спецификацию JavaScript для всех объектов, так что вы, скорее всего, придерживаетесь этого соглашения вместо того, чтобы реализовывать свой собственный метод. Это также менее вероятно сломать, чем реализация пользовательского метода, потому что .toString()
должен вызываться из любого свойства, тогда как.toValueString()
будет вызываться только для свойств, которые его реализуют.
РЕДАКТИРОВАТЬ: если ваш метод должен возвращать полностью настраиваемую строку для любого типа, то вам нужно убедиться, что вы связываете реализацию своего настраиваемого метода с существующими типами (Number, String, Boolean, Function, Object и т. Д.)
РЕДАКТИРОВАНИЕ 2: Как указывалось, переопределение реализации toString по умолчанию считается плохой практикой, поэтому другой идеей будет связать ваш пользовательский метод на уровне объектов, чтобы его можно было вызывать из чего угодно (поскольку практически все в JavaScript расширяет объект)
Object.prototype.toValueString = function() {
// return default implementation for this method;
}
CustomType.prototype.toValueString = function() {
// return specific implementation for this method;
}
Я немного запутался в вашем вопросе, но попробую.
В JS есть стандартный интерфейс для преобразования значения в строку: toString(). Это реализовано в Object, что означает, что все объекты (и примитивы, приведенные к объектам), будут иметь ожидаемое поведение.
var obj = {
age: 25,
customField: {
name: "test",
toString: function () { return this.name };
}
};
obj.age.toString(); // "25"
obj.customField.toString() // "test"
В качестве примечания я бы использовал только те переменные / ссылки, которые являются конструкторами функций (классы js). Это в значительной степени стандарт в сообществе.