I love learning new languages, even though I'm sure I'll probably never get to use them (at least not in production), or that the language will be so much different when I finally get to use it.
Same for frameworks and we can see great examples that steal from other languages and frameworks and are so much better for it.
If assignment
In Javascript the way of doing it is with a ternary:
const thatIsTheQuestion = Math.random() > 0.5 ? 'to do or not to do' : 'maybe I need better examples';
But sometimes we need something more robust to find that question
and the ternary doesn’t support it.
Now… This is something that I found genial while learning Rust.
let complex_question = if rand::random() {
let something_complex = 1;
something_complex * 2 // to return in rust just leave without `return` or semicolon!
} else {
let another_complex_thing = 2;
another_complex_thing * 3
};
For something like this we have multiple ways of doing that, not all of them as neat as the rust
example, but maybe we can come close… with IIFE!
IIFE (Immediately-Invoked Function Expressions)
Depending on when you started using Javascript you’ve probably used this a lot, a little, or maybe not even know what it is.
It’s a function you declare and execute in one go.
(() => {
console.log('this will simply execute')
})()
The cool thing about this is that you can assign the return to, let's say… a variable.
So, you could, in a way make that if assignment
.
const complexQuestion = (() => {
if (Math.random() > 0.5) {
const somethingComplex = 1;
return somethingComplex * 2;
} else {
const anotherComplexThing = 2;
return anotherComplexThing * 3
};
})()
Yes, you can refactor all of that in functions outside and call them instead of doing that, but I’m finding more and more places where doing an IIFE is just much clearer.
Pattern Matching
There are a lot of uses for that one, but with the popularity of Redux you might not even realize that the switch
you use in your reducers are a way of pattern matching.
But there are more elegant ways of doing that:
const whatToEat = {
breakfeast: 'bacon and eggs',
lunch: 'hamburger',
dinner: 'pizza',
}['what time is it?'] ?? 'junk food!';
You have the options and a default case!
And what do you know… it’s another way of doing a if assignment
.
const withBooleans = {
true: 'it works!',
false: 'nope'
}[Math.random() > 0.5];
// yes, it works for booleans too!
Everything together
const maybeTooMuch = (() => {
const complicatedStuff = {
true: () => 'after all, why not?',
false: () => (() => {
try {
throw new Error("why shouldn't I?");
} catch (error) {
return error.message;
}
})(),
default: null,
}[
(Math.random() > 0.66)
|| (
(Math.random() > 0.33)
? false
: 'default'
)
] ?? 'I probably gone too far on this one...';
try {
return complicatedStuff();
} catch {
return complicatedStuff;
}
})();
Maybe… maybe it was a little too much…
But basically, you have multiple ways of assigning things to a variable.
Bonus!
Maybe you didn’t like the way to handle defaults with the map… so…
function proxyfy(object, defaultValue) {
return new Proxy(object, {
get(target, prop) {
if (Reflect.has(target, prop)) {
return Reflect.get(...arguments);
}
return defaultValue;
},
});
}
const proxyfiedWhatToEat = proxyfy({
breakfeast: 'bacon and eggs',
lunch: 'hamburger',
dinner: 'pizza',
}, 'junk food!')
['what time is it?'];
Using Proxy
we can have a neater way of declaring what the default
should be.
Cover Photo by Janayara Machado on Unsplash