In this article I’ll share a few things I learned in JavaScript that I wished I had learned sooner. I’m not saying you should or shouldn’t use these techniques. Just that they exist, and understanding them will hopefully help you along.
Ternary Operations
Ternary operations allow you to simplify your conditional logic onto a nice, simple one-liner.
So instead of writing something like this:
const isHappy = true
let feelz
if (isHappy) {
feelz = 'good'
} else {
feelz = 'bad'
}
console.log(`I feel ${feelz}`)
We can write something like this:
const isHappy = true
const feelz = isHappy ? 'good' : 'bad'
console.log(`I feel ${feelz}`)
The only caveat is to remember that readability/maintainability is more important than slick one-liners. Ternaries can get out of hand quickly. For example:
const isHappy = true
const isHungry = false
const feelz = isHappy ? 'good' : isHungry ? 'grumpy' : 'bummed, but at least Im not hungry.'
console.log(`I feel ${feelz}`)
Type Coercion/Conversion/Casting
Type coercion (AKA. type conversion, String
Number
easily without the need for functions like parseInt
or parseFloat
.
// String to Number by prepending with plus sign
const strNum = "123.456"
console.log(strNum) // '123.456'
console.log(+strNum) // 123.456
console.log(typeof strNum) // string
console.log(typeof +strNum) // number
// Number to String by adding empty string
const num = 123.456
console.log(num) // 123.456
console.log("" + num) // '123.456'
console.log(num + "") // '123.456'
console.log(typeof num) // number
console.log(typeof "" + num) // string
// Boolean to Number by prepending with plus sign
console.log(true) // true
console.log(+true) // 1
console.log(false) // false
console.log(+false) // 0
// Various values to Boolean with double exclamation
console.log(!!1) // true
console.log(!!0) // false
console.log(!!'hello') // true
console.log(!!'') // false
console.log(!![]) // true
console.log(!!{}) // true
console.log(!!undefined) // false
console.log(!!NaN) // false
console.log(!!null) // false
// Date to Milliseconds by prepending with plus sign
const someDate = new Date()
console.log(typeof someDate) // object
console.log(typeof +someDate) // number
“It’s not a bug, it’s a feature.”
This “feature” of JavaScript comes as a result of being a weakly-typed language. When you understand it, you can use it to your advantage. When you don’t it can lead to your dismay.
Scientific Notation
For a long time, I was unaware of JavaScript’s ability to display numbers in scientific notation. It’s nothing revolutionary, but it does save some characters from time to time.
console.log(1000000 === 1e6) // true
console.log(0.000005 === 5e-6) // true
console.log(345000 === 3.45e5) // true
Accepting Multiple Options
Every once in a while, there is the need to test the same variable against multiple possible options, and perform the same task. As with most things, there are a few approaches.
My least favorite:
if (iAm === 'sad' || iAm === 'hungry' || iAm === 'tired') {
console.log('better do something about this')
}
A better way:
switch(iAm) {
case 'sad':
case 'hungry':
case 'tired':
console.log('better do something about this')
}
With ES6:
const options = ['sad', 'hungry', 'tired']
if(options.includes(iAm)) {
console.log('better do something about this')
}
Short-Circuit Evaluation
Short-circuit evaluation combines logical operators (&& or ||) with expressions. I realize that doesn’t really clarify what they do, but when you look at the code it will make more sense. By using them, we can write shorter expressions.
Default/fallback values:
// old way
let favoriteFood
if (someFood) {
favoriteFood = someFood
} else {
favoriteFood = "pizza"
}
// new way
const favoriteFood = someFood || "pizza"
The expression above will assign favoriteFood
to whatever "someFood"
is. If it is defined, the left side of the OR clause will be truthy and therefore it will not need to continue execution.
"someFood"
favoriteFood
will be “pizza”.
Optional function execution:
// old way
let bool = false
if (bool) {
console.log('so true!')
} else {
console.log('false!')
}
// new way
let bool = false
bool && console.log('so true!') // doesn't do anything
bool = true
bool && console.log('so true!') // logs "so true!"
Using the AND operand requires that both sides of the operation are truthy. If the left side is falsy, execution will not continue at all. If the left side is truthy, execution will continue to evaluate the right side.
All the practical applications for this may not be immediately obvious, but on place where it works well is if you write a function that takes an OPTIONAL callback function:
// old way
function doSomething(optionalCallback) {
// Do something here...
if(optionalCallback) {
optionalCallback()
}
}
// new way
function doSomething(optionalCallback) {
// Do something here...
optionalCallback && optionalCallback()
}
The examples above require a bit of knowledge about how JavaScript handles “truthy” and “
Which leads me into my last topic
Truthy and Falsy values
Boolean values (true, false) are inherently obvious whether they are true or false. But JavaScript also has values which it considers truthy and
Here are how the following values are treated:
// Truthy
const truthy = [
// the boolean 'true'
true,
// any non-empty string
'non-empty string',
'0',
'false',
// any non-zero number
1,
-1,
// any array (even empty ones)
[],
// any object (even empty ones)
{},
// any function (even empty ones)
function(){},
]
// Falsy
const falsy = [
// the boolean false
false,
// the number 0
0,
// an empty string
'',
// and these fluffs
null,
undefined,
NaN
]
So instead of checking if something is sort of equal to true, we can just check if it’s truthy:
// old way
if (someString.length > 0) {
console.log('truthy')
}
// new way
if (someString) {
console.log('truthy')
}
Another thing to note about truthy and falsy values is that they can be a little confusing or could lead to some errors. In the case where you need strict checking whether or not a value is true of false, you can convert any value to a boolean with the double-exclamation mark:
console.log(!!"I want to be a boolean") // true
Dynamic Object Keys
I don’t remember when I first learned this one, but I remember the feeling of the “aha” moment it brought. Sometimes you need to access an object key, but the key is programmatically determined.
Well, it’s actually quite simple. Just use square brackets.
const obj = {
name: "Austin"
language: "JavaScript"
}
let key = "name"
console.log(obj.name) // Austin
console.log(obj["name"]) // Austin
key = "name"
console.log(obj[key]) // Austin
console.log(obj.language) // JavaScript
console.log(obj["language"]) // JavaScript
key = "language"
console.log(obj[key]) // JavaScript
Closing thoughts
This article was intended to share some of the shortcuts I’ve picked up or seen along the way. It’s not to say that these are the best ways to implement the logic.
None of these patterns will make you a better developer, or make your code faster, or anything like that. In fact, with the wrong implementation, you could actually make things more complicated, buggy, or error-prone.
There is also
The main point is to recognize and understand these patterns. Whether you choose to use them is up to you, but you may run into them in someone else’s code base, and you will be better off for knowing how they work.
Thank you so much for reading. If you liked this article, and want to support me, the best ways to do so are to share it, sign up for my newsletter, and follow me on Twitter.
Originally published on austingil.com.