So there's those colors object configuration, that is something like this
color: {
main: "red",
light: "lightcoral"
dark: "darkred"
I think it is a bit cumbersome the color.main pattern popping up everywhere, instead of simply color. However, the color.variant part makes ton of sense.
So i wonder how can i easily (and if should i?!) create an object (or any object like entity) in Javascript/Typescript, that mix'em up. Returning a value by it self, just like a plain variable/getter, and still have it's variants on nested properties.
I'm not up to touch on prototype and too fancy stuff to make it for real though. But know all possibilies would be nice.
So to illustrate, the final object should act like this:
console.log(color) // red
console.log(color.light) // lightcoral
console.log(color.dark) // darkred
Generally speaking: no, because javascript isn't strong typed. Consider the following:
var a = redObject;
var b = a;
Now, why b should be the string "red" rather than a reference to the redObject?
This is not true for strong typed OO languages (not every ones anyway). For example in c++ you can define a custom conversion function for any type. So if you have
class Color {
operator int() const { return 255; }
operator char*() const { return "red"; }
}
Color a();
int b = a;
char* c = a;
then b would be 255 and c would be "red", bacause the compiler knows which conversion function it should use based on the type of the assigned variable.
However many OO languages have one implicit conversion function for the string type, which in most cases can be overridden. So you could create a custom Color class with a custom toString method to get what you want, but keep in mind that this will only work when converting the object to string, not for every variable assignment:
<span id="xx"></span>
<script>
function Color(main, light, dark) {
this.main = main;
this.light = light;
this.dark = dark;
}
Color.prototype.toString = function() {
return this.main;
};
var redObject = new Color("red", "lightcoral", "darkred");
console.log(redObject); // console displays: Color {main: "red", light: "lightcoral", dark: "darkred"}
console.log(''+redObject); // console displays: red
console.log(redObject.light); // console displays: lightcoral
console.log(redObject.dark); // console displays: darkred
$('#xx').text(redObject); // the span displays: red
</script>
Another option is to use a function, which give much more control, but I don't recommend it anyway:
function Color(main, light, dark) {
var result = function() {
return main;
};
result.light = light;
result.dark = dark;
return result;
}
var redObject = Color("red", "lightcoral", "darkred");
console.log(redObject()); // console displays: red
console.log(redObject.light); // console displays: lightcoral
console.log(redObject.dark); // console displays: darkred
A better way is to have a color map and use a function only to query light and dark variants:
var colors = {};
function defineColor(main, light, dark) {
colors[main] = {main: main, light: light, dark: dark};
}
function light(color) {
return colors[color].light;
}
function dark(color) {
return colors[color].dark;
}
defineColor("red", "lightcoral", "darkred");
var color = "red";
console.log(color); // console displays: red
console.log(light(color)); // console displays: lightcoral
console.log(dark(color)); // console displays: darkred