Что такое перечисление в моем мнении : это неизменный объект, который всегда доступен, и вы можете сравнивать элементы друг с другом, но элементы имеют общие свойства / методы, но сами объекты или значения не могут быть изменены, и они создаются только один раз.
Перечисления imho используются для сравнения типов данных, настроек, действий для принятия / ответа на подобные вещи.
Итак, для этого вам нужны объекты с одинаковым экземпляром, чтобы вы могли проверить, является ли это типом enum. if(something instanceof enum)
Также, если вы получаете объект enum, вы хотите иметь возможность что-то с ним делать, независимо от того, Тип enum, он всегда должен отвечать одинаково.
В моем случае сравниваются значения типов данных, но это может быть что угодно: от изменения блоков в направлении движения в трехмерной игре до передачи значений в реестр конкретных типов объектов.
Имея в виду, что это javascript и он не предоставляет фиксированный тип enum, вы в конечном итоге всегда делаете свою собственную реализацию, и, как показывает этот поток, существуют легионы реализаций, хотя одна из них не является абсолютной верностью.
Это то, что я использую для Enums. Поскольку перечисления неизменяемы (или должны быть хотя бы хе), я замораживаю объекты, чтобы ими нельзя было легко манипулировать.
EnumField.STRING может использовать перечисления, и они имеют свои собственные методы, которые будут работать с их типами. Чтобы проверить, передано ли что-либо объекту, вы можете использовать if(somevar instanceof EnumFieldSegment)
Возможно, это не самое элегантное решение, и я открыт для улучшений, но этот тип неизменяемого перечисления (если вы не разморозили его) точно нужный мне случай использования.
Я также понимаю, что мог бы переопределить прототип с помощью {}, но мой ум лучше работает с этим форматом ;-) пристрелите меня.
/**
* simple parameter object instantiator
* @param name
* @param value
* @returns
*/
function p(name,value) {
this.name = name;
this.value = value;
return Object.freeze(this);
}
/**
* EnumFieldSegmentBase
*/
function EnumFieldSegmentBase() {
this.fieldType = "STRING";
}
function dummyregex() {
}
dummyregex.prototype.test = function(str) {
if(this.fieldType === "STRING") {
maxlength = arguments[1];
return str.length <= maxlength;
}
return true;
};
dummyregexposer = new dummyregex();
EnumFieldSegmentBase.prototype.getInputRegex = function() {
switch(this.fieldType) {
case "STRING" : return dummyregexposer;
case "INT": return /^(\d+)?$/;
case "DECIMAL2": return /^\d+(\.\d{1,2}|\d+|\.)?$/;
case "DECIMAL8": return /^\d+(\.\d{1,8}|\d+|\.)?$/;
// boolean is tricky dicky. if its a boolean false, if its a string if its empty 0 or false its false, otherwise lets see what Boolean produces
case "BOOLEAN": return dummyregexposer;
}
};
EnumFieldSegmentBase.prototype.convertToType = function($input) {
var val = $input;
switch(this.fieldType) {
case "STRING" : val = $input;break;
case "INT": val==""? val=0 :val = parseInt($input);break;
case "DECIMAL2": if($input === "" || $input === null) {$input = "0"}if($input.substr(-1) === "."){$input = $input+0};val = new Decimal2($input).toDP(2);break;
case "DECIMAL8": if($input === "" || $input === null) {$input = "0"}if($input.substr(-1) === "."){$input = $input+0};val = new Decimal8($input).toDP(8);break;
// boolean is tricky dicky. if its a boolean false, if its a string if its empty 0 or false its false, otherwise lets see what Boolean produces
case "BOOLEAN": val = (typeof $input == 'boolean' ? $input : (typeof $input === 'string' ? (($input === "false" || $input === "" || $input === "0") ? false : true) : new Boolean($input).valueOf())) ;break;
}
return val;
};
EnumFieldSegmentBase.prototype.convertToString = function($input) {
var val = $input;
switch(this.fieldType) {
case "STRING": val = $input;break;
case "INT": val = $input+"";break;
case "DECIMAL2": val = $input.toPrecision(($input.toString().indexOf('.') === -1 ? $input.toString().length+2 : $input.toString().indexOf('.')+2)) ;break;
case "DECIMAL8": val = $input.toPrecision(($input.toString().indexOf('.') === -1 ? $input.toString().length+8 : $input.toString().indexOf('.')+8)) ;break;
case "BOOLEAN": val = $input ? "true" : "false" ;break;
}
return val;
};
EnumFieldSegmentBase.prototype.compareValue = function($val1,$val2) {
var val = false;
switch(this.fieldType) {
case "STRING": val = ($val1===$val2);break;
case "INT": val = ($val1===$val2);break;
case "DECIMAL2": val = ($val1.comparedTo($val2)===0);break;
case "DECIMAL8": val = ($val1.comparedTo($val2)===0);break;
case "BOOLEAN": val = ($val1===$val2);break;
}
return val;
};
/**
* EnumFieldSegment is an individual segment in the
* EnumField
* @param $array An array consisting of object p
*/
function EnumFieldSegment() {
for(c=0;c<arguments.length;c++) {
if(arguments[c] instanceof p) {
this[arguments[c].name] = arguments[c].value;
}
}
return Object.freeze(this);
}
EnumFieldSegment.prototype = new EnumFieldSegmentBase();
EnumFieldSegment.prototype.constructor = EnumFieldSegment;
/**
* Simple enum to show what type of variable a Field type is.
* @param STRING
* @param INT
* @param DECIMAL2
* @param DECIMAL8
* @param BOOLEAN
*
*/
EnumField = Object.freeze({STRING: new EnumFieldSegment(new p("fieldType","STRING")),
INT: new EnumFieldSegment(new p("fieldType","INT")),
DECIMAL2: new EnumFieldSegment(new p("fieldType","DECIMAL2")),
DECIMAL8: new EnumFieldSegment(new p("fieldType","DECIMAL8")),
BOOLEAN: new EnumFieldSegment(new p("fieldType","BOOLEAN"))});
Вы можете либо протестировать конкретный класс, используя оператор «is», либо использовать flash.utils.getQualifiedClassName () (вы передаете ему свой объект), который вернет строку полное имя класса.
Оператор "is" представляет один вариант.
Затем есть оператор instanceof , который может оказаться полезным, а может и не оказаться полезным в зависимости от ситуации.
Также существует класс ObjectUtil со статическим методом getClassInfo . Этот возвращает не только имя класса объекта.
Оператор typeof, к сожалению, бесполезен для классов.
И, как уже предположил Бранден Холл, flash.utils.getQualifiedClassName () .
вот простой псевдокод, демонстрирующий, как использовать оператор is
для того, что вы хотите сделать:
for each (var item:* in myArray)
{
if (item is TextInput)
doSomethingWithTextInput(item as TextInput);
else if (item is RadioButton)
doSomethingWithRadioButton(item as RadioButton);
}
Оператор есть
проверяет совместимость типов, да. Из документации is
:
... оценивает, является ли объект совместим с определенным типом данных, класс или интерфейс. Используйте
равно
оператор вместоinstanceof
оператор для сравнения типов. Ты можешь также используйте операторis
для проверки реализует ли объект интерфейс.
Другими полезными операторами в этой категории являются typeof
(который возвращает строковое представление примитива), instanceof
(аналогично is
, но игнорирует совместимость интерфейса) и как
. Большой и полный список операторов ActionScript доступен здесь .
Надеюсь, это поможет!
Лучше всего использовать оператор «is» и использовать что-то вроде:
for( var i:int = 0; i < componentArr.length; i++ )
{
var comp:UIComponent = componentArr[ i ];
if( comp is DataGrid )
// Handle DataGrid functionality here.
else if (comp is DropDown )
// Handle DropDown here
}
Однако у этого подхода есть одна проблема. Поскольку "is" вернет истину для всех классов-потомков, вы должны поместить все классы-потомки перед их предками - List должен стоять перед ListBase. Это может вызвать некоторые неудобства.
// This is important to remember:
var mc:MovieClip = new MovieClip();
trace( mc is Sprite ); // true
Есть еще один вариант для случаев, когда вы хотите, чтобы объекты были членами определенного класса (а не класса-потомка): вы можете использовать свойство конструктора объекта и использовать оператор switch .
for( var i:int = 0; i < componentArr.length; i++ )
{
var klass:Class = componentArr[ i ].constructor;
switch( klass )
{
case DataGrid:
// Handle DataGrid
break;
case Text:
// Handle Text
break;
case NumericStepper:
// Handle NumericStepper
break;
default:
// Handle default
break;
}
}
Попробуйте использовать свойство className.
Оно должно возвращать TextInput или Button в зависимости от случая
for each (var item:* in myArray)
{
if(item.hasProperty('className'))
{
trace("item ["+i+"] is :" + item['className']);
}
}
ЕГО РАБОТА :)
Я решил эту проблему следующим образом
switch( true )
{
case item is Customer_SF:
c = item as Customer_SF;
break;
case item is Opportunity:
o = item as Opportunity;
break;
case item is Product:
o = ( item as Product )._opportunity;
break;
default:
return true;
}