2014-02-20 4 views
1

С помощью этого скрипта я добавить переменные объекта во время выполнения: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; 
})(); 

Remember, toString() встроен в спецификации JavaScript для всех объектов, так что вы бы скорее всего придерживаться так конвенции переопределяя это, а не реализуя свой собственный метод. Это также с меньшей вероятностью прерывается, чем реализация настраиваемого метода, потому что .toString() должен быть вызван из любого свойства, тогда как. toValueString() будет доступен только для свойств, которые его реализуют.

EDIT: Если ваш метод должен возвращать полностью настраиваемую строку, для любого типа, то вам необходимо убедиться, что вы свяжете свою реализацию пользовательского метода для выхода из типов (Number, String, Boolean, функция, объект и т.д.)

EDIT 2: Как было отмечено, перекрывая реализацию по умолчанию ToString считается плохой практикой, поэтому еще одна идея будет связать свой собственный метод на уровне объекта, так что вызываемая из ничего (так как практически все в JavaScript extends Object)

Object.prototype.toValueString = function() { 
    // return default implementation for this method; 
} 

CustomType.prototype.toValueString = function() { 
    // return specific implementation for this method; 
} 
+2

Я бы не советовал переопределять toString, поскольку он нехорошо применим к объектам, которые вы не владеете (подумайте о библиотеке PrototypeJs, которая отсутствовала по сравнению с чем-то вроде jQuery). Стандартные/нативные объекты должны вести себя так, как ожидалось. – pbo

+0

Спасибо за ваш ответ, не плохая идея, но, как сказал pbo, я не хочу переопределять значение по умолчанию toString() всех этих объектов. – Kooki

+0

@Kooki, см. Мое второе редактирование – series0ne

1

Я немного смущен вашим вопросом, но я сделаю это.

В JS существует стандартный интерфейс для преобразования значения в строку: toString().Это реализовано в Object, что означает, что все объекты (и примитивы, отнесенные к объектам) будут иметь ожидаемое поведение.

var obj = { 
    age: 25, 
    customField: { 
     name: "test", 
     toString: function() { return this.name }; 
    } 
}; 

obj.age.toString(); // "25" 
obj.customField.toString() // "test" 

В качестве побочного примечания я использовал бы только переменные/ссылки, которые являются конструкторами функций (классы js). Это довольно стандартно в сообществе.

+0

Спасибо за ваш ответ, но 'obj.customField.toString()' не работал для меня, потому что он возвращает такое же жуткое имя, как obj.customField ('PropertyObjectImpl [id = abc123, data = Some Data, type = Node, order = 42] '), и я не влияю на этот объект или его функции ... – Kooki

+0

Js является динамическим, вы можете расширить эти объекты или просто установить их с помощью метода toString? – pbo

+0

Другой вариант - обернуть каждый из этих объектов, чтобы они соответствовали любому интерфейсу. Object.create (propertyObject) - это один из способов, когда вы создадите новый объект, который наследуется от него. Затем с возвратом добавьте toString – pbo

Смежные вопросы