Javascript Enum To Corresponding String Value
So I have this in the javascript for my page:
var TEST_ERROR = {
'SUCCESS' : 0,
'FAIL' : -1,
'ID_ERROR' : -2
};
And perform tests on functions in the page like so:
function test()
{
// Get the paragraph from the DOM
var testResultParagraph = document.getElementById('testResult');
// Check the paragraph is valid
if(!testResultBox)
{
// Update the web page
testResultParagraph.value = TEST_ERROR.ID_ERROR;
return TEST_ERROR.ID_ERROR;
}
// Something to store the results
var testResult = TEST_ERROR.SUCCESS;
// Test the calculation
testResult = testCalculate()
// Update the web page
testResultParagraph.value = testResult;
// The test succeeded
return TEST_ERROR.SUCCESS;
}
The result of testCalculate()
and the value of the paragraph will be either 0, -1, -2 depending on the outcome.
Now I want to map this to a string so that the paragraph shows 'Success', 'Fail' or 'ID Error'
I could do this a few ways I have figured:
var TEST_ERROR = {
'SUCCESS' : {VALUE : 0 , STRING: 'Success' },
'FAIL' : {VALUE : -1, STRING: 'Fail' },
'ID_ERROR' : {VALUE : -2, STRING: 'Id Error'},
};
would require a modification to the enum dot accessors, or
var TEST_ERROR = {
'SUCCESS' : 0,
'FAIL' : 1,
'ID_ERROR' : 2
};
var TEST_STRING = [
'Succ开发者_如何学编程ess',
'Fail',
'ID Error'
];
Which would require changes to the logic (result > TEST_ERROR.SUCCESS
seems wierd tho!)
My question is how would you go about mapping an enumerator value to a string value in Javascript? I'm thinking the second way is the most sensible, but would like the enumerator to be positive for successes and negative for fails. I also like the idea of the first containing the strings and values in the object structure.
Any ideas?
Thanks!
Matt
PS. I'm going to be doing the testing in a Web Worker, so that the page doesn't hang and the results will be put into a table, not a paragraph like above.
PPS. I'm pretty new to Javascript programming, but do a lot in ASM, C, C++, C#.
Do you actually need the numeric values at all? If not then you could use something like this:
var TEST_ERROR = {
SUCCESS : 'Success',
FAIL : 'Fail',
ID_ERROR : 'ID Error'
};
Not quite optimal, but the cleanest you can get without pre-computing the reverse dictionary (and besides, this shouldn't be too much of an issue if you only have a few enumeration values):
function string_of_enum(enum,value)
{
for (var k in enum) if (enum[k] == value) return k;
return null;
}
For TypeScript, there is a simpler solution (Please ignore my answer if you stick with JS):
export enum Direction {
none,
left = 1,
right = 2,
top = 4,
bottom = 8
}
export namespace Direction {
export function toString(dir: Direction): string {
return Direction[dir];
}
export function fromString(dir: string): Direction {
return (Direction as any)[dir];
}
}
console.log("Direction.toString(Direction.top) = " + Direction.toString(Direction.top));
// Direction.toString(Direction.top) = top
console.log('Direction.fromString("top") = ' + Direction.fromString("top"));
// Direction.fromString("top") = 4
console.log('Direction.fromString("xxx") = ' + Direction.fromString("unknown"));
// Direction.fromString("xxx") = undefined
Because the enumeration type is compiled into an object(dictionary). You don't need a loop to find the corresponding value.
enum Direction {
left,
right
}
is compiled into:
{
left: 0
right: 1
0: "left",
1: "right"
}
I prefer the below method.
enum ColorEnum {
Red,
Green,
Blue
}
console.log(ColorEnum[ColorEnum.Red]);
You could always have the values be objects of a particular type.
var TEST_ERROR = (function() {
function ErrorValue(value, friendly) {
this.value = value;
this.friendly = friendly;
}
ErrorValue.prototype = {
toString: function() { return this.friendly; },
valueOf: function() { return this.value; }
};
return {
'SUCCESS': new ErrorValue(0, 'Success'),
'FAIL': new ErrorValue(1, 'Fail'),
'ID_ERROR': new ErrorValue(2, 'ID error')
};
})();
Now when you get a value of that type:
var err = testFunction(whatever);
you can get the string value with
alert(err.toString());
In fact you shouldn't even have to call .toString()
explicitly, most of the time.
If you are typescript, then you will already have a definition for the enum. Else you can directly use the JS version of the enum.
var Status;
(function (Status) {
Status[Status["New"] = 0] = "New";
Status[Status["Submitted"] = 1] = "Submitted";
Status[Status["Approved"] = 2] = "Approved";
Status[Status["Rejected"] = 3] = "Rejected";
})(Status || (Status = {}));
var snew = Status.New;
console.log(snew); //This is the number
console.log(Status[snew]); //This is the string
The best way to do it is:
export const UserLevel = Object.freeze({
BABY: 1,
CHILED: 2
});
Why we need to add freeze UserLevel is const but we can change the values inside, so freeze will make it safe for changes.
This might be different from what you want but I want to share my answer. This was inspired by @LukeHconst solution. Consider bookCategory
below you will notice that I'm using a number as a key.
const bookCategory = {
"0": "Biography",
"1": "Fiction",
"2": "History",
"3": "Mystery",
"4": "Suspense",
"5": "Thriller"
};
I wrote the bookCategory
like this because if you are using an enum column in MySQL. For example,
category ENUM ('0', '1', '2', '3', '4', '5')
You would need some kind of conversion in JavaScript. So I came up with this and the usage is simple as:
bookCategory[book.category]
Building on Victor's excellent answer, so it works in TypeScript:
enumToStr(enumeration: any, value: any): string {
for (var k in enumeration)
if (enumeration[k] == value)
return <string>k;
return null;
}
精彩评论