Java enums are very sophisticated and you can create enums with multiple fields and methods as follows.
Java.Color.java
enum Color {
RED("Red", 255, 0, 0),
YELLOW("yellow", 255, 255, 0),
GRAY("gray", 155, 155, 155);
Color(String name, int r, int g, int b) {
this.name = name;
this.r = r;
this.g = g;
this.b = b;
}
public String name;
public int r, g, b;
public String toHexCode() {
return String.format("#%02x%02x%02x", r, g, b);
}
}
System.out.println(Color.YELLOW.toHexCode()); // => "#ffff00"
System.out.println(Color.GRAY.name); // => "gray"
If you implement this obediently with JavaScript, it will surely look like this.
JavaScript.color.js
var Color = (function() {
var InnerType = function(name, r, g, b) {
this.name = name;
this.r = r;
this.g = g;
this.b = b;
};
InnerType.prototype.toHexCode = function() {
return '#' + ('00' + this.r.toString(16)).slice(-2) + ('00' + this.g.toString(16)).slice(-2) + ('00' + this.b.toString(16)).slice(-2);
};
return {
RED : new InnerType('Red', 255, 0, 0),
YELLOW : new InnerType('yellow', 255, 255, 0),
GRAY : new InnerType('gray', 155, 155, 155)
};
})();
console.log(Color.YELLOW.toHexCode()); // => "#ffff00"
console.log(Color.GRAY.name); // => "gray"
It looks good at first glance, but ... In Java, it is natural to use this enum as the key of Map.
Map<Color, Integer> colorNums = new HashMap<>();
colorNums.put(Color.RED, 10);
colorNums.put(Color.YELLOW, 20);
colorNums.put(Color.GRAY, 30);
System.out.println(colorNums.get(Color.RED)); // => "10"
System.out.println(colorNums.get(Color.YELLOW)); // => "20"
In the JavaScript version,
var colorNum = {};
colorNum[Color.RED] = 10;
colorNum[Color.YELLOW] = 20;
colorNum[Color.GRAY] = 30;
console.log(colorNum[Color.RED]); // => "30" !!?
console.log(colorNum[Color.YELLOW]); // => "30" !!?
And it doesn't behave as intended. Since Color.RED, Color.YELLOW, and Color.GRAY are objects, the default toString of the object is called when it becomes the key of the associative array, and all three become "[object Object]". Cause.
So, if you try to return a unique string for each with toString as follows, it will work as intended.
JavaScript.color_fix.js
var Color = (function() {
const InnerType = function(name, r, g, b, toStringValue) {
this.name = name;
this.r = r;
this.g = g;
this.b = b;
this.toString = function() {
return toStringValue;
};
};
InnerType.prototype.toHexCode = function() {
return '#' + ('00' + this.r.toString(16)).slice(-2) + ('00' + this.g.toString(16)).slice(-2) + ('00' + this.b.toString(16)).slice(-2);
};
return {
RED : new InnerType('Red', 255, 0, 0, 'RED'),
YELLOW : new InnerType('yellow', 255, 255, 0, 'YELLOW'),
GRAY : new InnerType('gray', 155, 155, 155, 'GRAY')
};
})();
var colorNum = {};
colorNum[Color.RED] = 10;
colorNum[Color.YELLOW] = 20;
colorNum[Color.GRAY] = 30;
console.log(colorNum[Color.RED]); // => "10"
console.log(colorNum[Color.YELLOW]); // => "20"
I'm happy.
However, it's a little disappointing to specify the character string for toString by myself, so if you can use ES6, it's better to automate it using Symbol ().
JavaScript.color_fix_es6.js
const Color = (() => {
const InnerType = function(name, r, g, b) {
this.name = name;
this.r = r;
this.g = g;
this.b = b;
const sym = Symbol();
this.toString = () => sym;
};
InnerType.prototype.toHexCode = function() {
return '#' + ('00' + this.r.toString(16)).slice(-2) + ('00' + this.g.toString(16)).slice(-2) + ('00' + this.b.toString(16)).slice(-2);
};
return {
RED : new InnerType('Red', 255, 0, 0),
YELLOW : new InnerType('yellow', 255, 255, 0),
GRAY : new InnerType('gray', 155, 155, 155)
};
})();
Java's enum is the strongest, but the flexibility of JavaScript that can achieve almost the same thing is good.
Recommended Posts