This article includes a round-up of some popular JavaScript shorthand coding techniques for beginners, which can be good for code optimization or minification purposes.
Assignment Operators Shorthand
Name | Shorthand operator | Meaning |
---|---|---|
Addition Assignment | x += y |
x = x + y |
Subtraction Assignment | x -= y |
x = x - y |
Multiplication Assignment | x *= y |
x = x * y |
Division Assignment | x /= y |
x = x / y |
Remainder Assignment | x %= y |
x = x % y |
Boolean Comparison Shorthand
The conventional way:
const value = true; if (value === true) { // do something }
The shortcut way:
const value = true; if (value) { // do something }
Get a Character From String Shorthand
The conventional way:
'string'.charAt(1); // output: t
The shortcut way:
'string'[1]; // output: t
Create a Link Shorthand
The conventional way:
const lnk = '<a href="https://www.google.com/">Google</a>';
The shortcut way:
const lnk = 'Google'.link('https://www.google.com/'); // output: <a href="https://www.google.com/">Google</a>
Although, the link()
method has good browser support, still you should use it with caution as it is not a part of the standards, and may not work as expected in all browsers.
Create an Array Shorthand
The conventional way:
const people = new Array('john', 'jane');
The shortcut way:
const people = ['john', 'jane'];
Create an Object Shorthand
The conventional way:
const obj = new Object(); obj.a = 1; obj.b = 2; obj.c = 3;
The shortcut way:
const obj = {a: 1, b: 2, c: 3}; // use for loop to iterate over the properties of the object for (let [key, value] of Object.entries(obj)) { console.log(`obj.${key} = ${value}`); } // output: // "obj.a = 1" // "obj.b = 2" // "obj.c = 3"
Please note that leaving a trailing comma before the closing curly brace can cause a problem in IE when declaring object properties.
Regular Expressions Testing Shorthand
The conventional way:
const pattern = new RegExp('world', 'i'); // case insensitive lookup pattern.test('Hello World'); // output: true
The shortcut way:
/world/i.test('Hello World'); // output: true
Shorthand Using the Comma Operator
The comma operator evaluates each of its operands (from left-to-right) and returns the value of the last operand. This means that the following (and much more) is possible:
let i = 0; do { console.log(i); } while (i++, i < 4); // output: // 0 // 1 // 2 // 3
Consider another example where we process operands before returning. As stated, only the last operand will be returned but all others are going to be evaluated as well.
let a = 1; function x() { return (a = 45, a += 1); } alert(x()); // output: 46
Using the Ternary (conditional) Operator
Common Usage:
The ternary operator is usually used as a shortcut for if
else
statement.
The conventional way:
if (cost > 10) { alert('Expensive'); } else { alert('Cheap'); }
The shortcut way:
alert((cost > 10) ? 'Expensive' : 'Cheap');
Other Usage:
Ternary operator can be used to shorten function calling. For example, conventionally if we do:
function add(item) { alert(`added: ${item}`); } function remove(item) { alert(`removed: ${item}`); } const inventory = 'low'; const product = 'shirt'; if (inventory === 'low') { add(product); } else { remove(product); } // output: added: shirt
This can be re-written in a shorter way as:
function add(item) { alert(`added: ${item}`); } function remove(item) { alert(`removed: ${item}`); } const inventory = 'low'; ((inventory === 'low') ? add : remove)('shirt'); // output: added: shirt
Similarly, we can use the same technique with objects to dynamically select a specific object property based on a condition, for example:
const inventory = 'low'; const stock = { add: function(item) { alert(`added: ${item}`); }, remove: function(item) { alert(`removed: ${item}`); } }; stock[(inventory === 'low') ? 'add' : 'remove']('shirt'); // output: added: shirt
Ternary evaluations can also be used to perform different operations, for example:
let stop = false; const age = 16; (age > 18) ? location.href('continue.html') : stop = true; // output: stop = true
More than one operation can be evaluated as well for each case by grouping operations using ()
(brackets) and separating each one with a ,
(comma operator), like so:
let stop = false; const age = 23; const access = (age > 18) ? ( alert('Allowed!'), 'Access Granted!' ) : ( stop = true, alert('Not Allowed!'), 'Access Denied!' ); console.log(access); // output: Access Granted!
Remember that the comma operator evaluates all operands but returns only the last.
Shorthand Coding With Truthy and Falsy
In JavaScript, all values are truthy unless they are defined as falsy:
Truthy (values that evaluate to true
):
if (true) // true if ('0') // true if ('string') // true if ([]) // true if ({}) // true if (new Date()) // true if (1) // true
Falsy (values that evaluate to false
):
if (false) // false if (0) // false if (0.0) // false if ("") // false if ('') // false if (``) // false if (null) // false if (undefined) // false if (NaN) // false
Please note that there are a few other values (that are not very commonly used) that are considered falsy in JavaScript. If you wish to learn more about falsy values in JavaScript, then check out another post dedicated to that topic.
With that information, code like the following is possible:
let i = -5; while (i++) { // runs till i = 0 since 0 is a falsy value }
indexOf()
Shorthand
String Contains:
The conventional way:
'string'.indexOf('ring') !== -1; // output: true
The shortcut way:
~'string'.indexOf('ring'); // output: -3 (which is a truthy value)
String Does Not Contain:
The conventional way:
'string'.indexOf('a') === -1; // output: true
The shortcut way:
~'string'.indexOf('a'); // output: 0 (which is a falsy value)
This works because ~
is a bitwise negation operator which inverts the binary digits of an operand. To make things simple, bitwise NOT-ing any number n
yields -(n + 1)
. For example, ~5
yields -6
. That means when indexOf
returns -1
the bitwise negation of that (~-1
) equals 0
which is falsy value in JavaScript, which makes the boolean evaluation equal false
. This also means that all non-zero values would be truthy.
Type Casting Shorthands
Converting to Boolean:
By converting a value into strict Boolean data type, we can check whether it evaluates to truthy or falsy. A quick way to do this is to use the negation operator (!
):
let a; // a = undefined // if falsy (i.e. if false, 0, "", '', null, undefined, NaN) if (!a) { // do something }
Similarly, if we wanted to check if a value is non-falsy (or truthy), we could use the negation operator twice, like so:
const a = 1; // if truthy if (!!a) { // do something }
Converting to Number:
The conventional way:
const num = parseInt('10'); console.log(typeof num); // output: number
The shortcut way:
const num = +'10'; // using the unary + operator console.log(typeof num); // output: number const num = -'10'; // using the unary - operator console.log(typeof num); // output: number
The unary plus (+
) operator precedes its operand and evaluates it, but attempts to convert it into a number if it isn't already. Although unary negation (-
) can also convert non-numbers, unary plus is the fastest and preferred way of converting something into a number, because it does not perform any other operations on the number. It can convert string representations of integers and floats, as well as the non-string values such as true
, false
, and null
.
// common scenarios with unary plus (+) operator +3 // 3 +'3' // 3 +true // 1 +false // 0 +null // 0
// common scenarios with unary negation (-) operator -3 // -3 -'3' // -3 -true // -1 -false // -0 -null // -0
Converting to String:
The conventional way:
const num = 10; const str = String(num); console.log(typeof str); // output: string
The shortcut way:
const num = 10; const str = '' + num; // prefix (or suffix) empty string console.log(typeof str); // output: string
It can convert integers and floats, as well as the non-string values such as 0
, true
, false
, null
, undefined
, and NaN
.
('' + 0); // output: 0 (string) ('' + true); // output: true (string) ('' + false); // output: false (string) ('' + NaN); // output: NaN (string) ('' + undefined); // output: undefined (string) ('' + null); // output: null (string)
Self-Calling Anonymous Functions
Also known as Immediately Invoked Function Expression (IIEF), these are self-calling anonymous functions that execute automatically when the code is parsed by the browser for the first time. It has the following syntax:
(function(){ // some code that will be executed automatically })();
These anonymous functions can be useful to encapsulate code in its own namespace and protect code against variable name clashes.
This style of anonymous function wrapping is especially useful when working with multiple JavaScript libraries to avoid conflicting code. Consider the following example for jQuery JavaScript library:
(function($) { // some code that will be executed automatically })(jQuery);
We pass the jQuery
JavaScript object as an argument to the anonymous function, which allows us to use $
within the function expression without raising any potential conflicts with other code elsewhere in the document.
Other Syntax:
There are other ways to evaluate and directly call the function expression which, while different in syntax, behave the same way.
!function() {}(); +function() {}(); (function() {}());
Shorthand Coding by Short-Circuiting Evaluations
The boolean operators &&
(AND) and ||
(OR) perform short-circuited evaluation, which means when evaluating boolean operators, only as many arguments are evaluated as necessary to determine the outcome of a boolean expression.
As logical expressions are evaluated left-to-right, they are tested for possible "short-circuit" evaluation using the following rules:
false && (anything)
is short-circuit evaluated tofalse
.true || (anything)
is short-circuit evaluated totrue
.
For example, in the conjunction x && y
, if x
evaluates to false
, the whole expression will be false
, regardless of what the other argument evaluates to. Similarly, for a disjunction x || y
, if the first argument evaluates to true
, the whole expression will be true
, regardless of what the other argument evaluates to. The following truth table illustrates this AND and OR boolean logic:
x | y | x && y | x || y |
---|---|---|---|
false |
false |
false |
false |
false |
true |
false |
true |
true |
false |
false |
true |
true |
true |
true |
true |
With that knowledge, consider the following conventional code:
const count = null; if (null !== count) { return count; } else { return 1; } // output: 1
That can be re-written in a shorter way as such:
const count = null; return count || 1; // output: 1
Keep in mind that the &&
and ||
logical operators in JavaScript themselves do not return a boolean value (true
or false
), but instead the value of the last operand they evaluate.
Therefore, the shorthand code above evaluates to 1
because count
is null
which is a falsy value, so the ||
(OR) logical operator moves to evaluate the second operand which is a truthy value 1
.
Specifying Default Values:
Using short-circuiting technique can be a good way for specifying default values to variables:
function a(b) { // if the first operand is falsy, the default value is used b = b || 'hello world'; console.log(b); // output: hello world } a(); // call function with no argument
You should note though, that all falsy values (which includes the number 0
) will be evaluated as false
. So, if in the code above, value of b
was passed as the number 0
it would return the string "hello world" instead which might not be the result you expect in some cases.
Set Value If Truthy:
const a = 1; const b = (a && a.toString()); console.log(b); // output: 1 console.log(typeof b); // output: string
The variable b
would only be of type string if a
is a truthy value. Consider the case below where a
is undefined
(falsy):
let a; const b = (a && a.toString()); console.log(typeof b); // output: undefined
Eager (Non-Short-Circuited) Evaluations
There may be some instances where we may want to have non-short-circuited or eager evaluation, i.e. we would like to continue evaluating operands even if the first operand in the boolean conjunction x && y
evaluates to false
, or conversely the first boolean operand in the disjunction x || y
evaluates to true
.
In JavaScript, we could use the bitwise operators &
and |
which are eager, and yield identical truth tables:
x | y | x && y | x & y | x || y | x | y |
---|---|---|---|---|---|
false |
false |
false |
0 | false |
0 |
false |
true |
false |
0 | true |
1 |
true |
false |
false |
0 | true |
1 |
true |
true |
true |
1 | true |
1 |
In the table you'll notice that &
and |
bitwise operators yield identical truth tables to the &&
and ||
logical operators, with the exception being that the result of short-circuited evaluation produces boolean values (true
or false
) while the result of the eager evaluation produces integer values (0
or 1
).
The important difference to notice here is that the bitwise operators return 1
or 0
. In order to conduct boolean evaluations, we need to convert them into strict boolean types. This is possible since the result of the bit-wise operators is identical to the truth tables of &&
and ||
logical operators. Therefore, we can simply type cast these into strict boolean types by using double not (!!
) which would yield the following truth table:
x | y | x && y | !!(x & y) | x || y | !!(x | y) |
---|---|---|---|---|---|
false |
false |
false |
false |
false |
false |
false |
true |
false |
false |
true |
true |
true |
false |
false |
false |
true |
true |
true |
true |
true |
true |
true |
true |
So, the main difference here is &
and |
do not do short-circuit evaluation in boolean expressions, which means:
- While
&&
will stop evaluating if the first operand isfalse
,&
won't. - While
||
will stop evaluating if the first operand istrue
,|
won't.
This could be very useful, especially in cases where we want to evaluate all operands regardless of their boolean outcome. One such instance could be form validation, where we may not want to stop after encountering the first invalid field (which is what may happen in a short-circuited evaluation). We may instead want to validate all fields to highlight to the user all the invalid ones. Consider the following jQuery example:
HTML:
<form> <input type="text" id="name" name="name" /> <input type="text" id="email" name="email" /> <input type="text" id="msg" name="msg" /> <input type="submit" /> </form>
jQuery:
const field1 = $('#name'); const field2 = $('#email'); const field3 = $('#msg'); function validate(field) { // check if field is invalid const isInvalid = (field.val() === ''); // toggle invalid class using ternary operator field[((isInvalid) ? 'add' : 'remove') + 'Class']('invalid'); // flipping isInvalid, returns true when field is valid return !isInvalid; } $('form').on('submit', function() { // do an eager evaluation of all fields const isValid = !!(validate(field1) & validate(field2) & validate(field3)); // output result alert(isValid); // form is only submitted when all fields are valid (or truthy) return isValid; });
The eager evaluation code helps us evaluate all fields and accordingly adds or removes the invalid
class on all invalid fields. The form is only submitted when the conjunction is true
.
The same example in short-circuited evaluation would have stopped after the first invalid field.
This post was published (and was last revised ) by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.