25 JavaScript Tricks You Need To Know About (Part 2)

You can read about part one of 25 Javascript tricks in another article where you can find equally awesome code solution snippets to improve your codebase with and learn more about Javascript by examples.

Code Source

These are code snippets you can use in your projects and evolve to become something bigger. They teach various lessons and reveal great features of Javascript and the Environment where it runs. All code links are below the images.

Check Also:

1 — Deep value retriever

This simple function leverages the power of the Array reduce method to allow you to retrieve the deep value in deeply nested objects, array, and Javascript Map. You can access value belonging to the object itself or its prototype, like accessing a string length or getting the size of a Map.

Code on Github
deepValue(obj, 'top.in.list.0'); // get list 1st item
deepValue(obj, 'top.in.list.length'); // get list length
deepValue(obj, 'top.in.noExistentKey'); // returns null

2 — Date Formatter

Javascript Date is already powerful if you take time to learn it a little. Combined with the Intl object it becomes limitless. This is a small sample of a date formatter that even handles Internationalization that can be extended and modified to fulfill the needs of your project.

Code on Github
formatDate(Date.now(), 'MM-DD-YYYY'); 
// "02-06-2021"
formatDate(Date.now());
// "February 06, 2021"
formatDate(Date.now(), 'D de MMMM de YYYY', 'pt');
// "6 de fevereiro de 2021"
formatDate(Date.now(), 'MMMM DD, YYYY', 'zh');
// "二月 06, 2021"
formatDate(Date.now(), 'MMM DD (DDD), YYYY');
// "Feb 06 (Sat), 2021"

3 — Promisifier

NodeJs promisify utility is one of my favorite utils in NodeJs and I decided I need that in the client as well so I created this replica that handles any type of functions including async function, callback function, and those which simply return results.

Code on Github

Here is an example of usage with an “add” function that returns a result and a divide function that takes a callback and may throw or call the callback with the result.

const add = (a, b) => {
return a + b;
}
const divide = (a, b, cb) => {
if(b === 0 && a !== 0) {
cb(new Error('Cannot divide by "Zero"'), null)
} else {
const total = a / b;
cb(null, total);
}
}
const asyncAdd = promisify(add);
const asyncDivide = promisify(divide);
add(23, 67); // 90asyncAdd(23, 67).then(total => {
console.log(total); // 90
});
divide(35, 5, (error, total) => {
console.log(error) // null
console.log(total) // 7
});
divide(8, 0, (error, total) => {
console.log(error) // Error: 'Cannot divide by "Zero"'
console.log(total) // 'total' null
});
asyncDivide(35, 5)
.then((total) => {
console.log(total); // 7
});
asyncDivide(35, 0)
.catch((error) => {
console.log(error); // Error: 'Cannot divide by "Zero"'
});

4 — Merge Objects

Especially in react, you will feel the need to merge two objects without having to deal with the deep nesting and still maintain the structure. This simple snippet will deep merge your objects and array nicely using the power of recursion to return a new copy to you. It can be extended to support more object types as you wish.

Code on Github

5 — Deep Equality

Checking if 2 objects are equal may require you to do a lot and can be expensive. I always wanted something that is simple and extensible and this snippet does that. It can be extended to include checks for different types of objects as you can see in lines 7, 9, 12, and 13.

Code on Github

6 — Siblings selector

jQuery has some useful siblings selector. In fact, these are super simple methods you can create on your own. Below is a simple command object that allows you to access element siblings easily and efficiently.

Code on Github
element('ul li:nth-of-child(3)').siblings
element('.item-3').previousSiblings
element
(document.getElementById('section-4')).nextSiblings

7 — Ancestor selector

Similar to siblings, you may need to select an ancestor element that is not the direct parent of your element. You can do that with this simple built-in capability.

<section id="top">
<div><span>text</span></div>
<form action="">
<fieldset>
<label for="">
<input type="">
</label>
</fieldset>
</form>
</section>
const input = document.querySelector('input');input.parentElement // "<label for=''>...</label>"
input.closest('form') // "<form action=''>...</form>"
input.closest('#top') // "<section id='top'>...</section>"

8 — Key list by

You can change lists like array or map and even objects to be keyed by a specific value. This allows you to create maps easily from other data which can help for quicker data retrieving and check.

Code on Github
const arr = [
{id: 1, name: 'one'},
{id: 2, name: 'two'},
{id: 3, name: 'three'},
];
keyBy(arr, 'id');
/* outputs
{
'1': { id: 1, name: 'one' },
'2': { id: 2, name: 'two' },
'3': { id: 3, name: 'three' }
}
*/
const obj = {
1: {id: 1, str: 'uno'},
2: {id: 2, str: 'doz'},
3: {id: 3, str: 'tres'}
}
keyBy(obj, 'str');
/* outputs
{
uno: { id: 1, str: 'uno' },
doz: { id: 2, str: 'doz' },
tres: { id: 3, str: 'tres' }
}
*/
const map = new Map([
['one', {id: 1, name: 'one'}],
['two', {id: 2, name: 'two'}],
['three', {id: 3, name: 'three'}]
]);
keyBy(map, 'name');
/* outputs
{
one: { id: 1, name: 'one' },
two: { id: 2, name: 'two' },
three: { id: 3, name: 'three' }
}
*/

9 — Loop Anything with the ability to break out

Javascript while and for loops accept the “break” keyword in the body that allows them to quit early and avoid unnecessary iterations. My wish is to loop any data type easily with the same ability to break out.

The following allows you to loop any iterable with the option to break out of the loop by making your callback return true. It can also be extended to create other methods similar to many of the other Array methods.

Code on Github
forEach([1, 2, 3], console.log) // array
forEach('123', console.log) // string
forEach({a: 1, b: 3, c: 4}, console.log) // object
forEach(new Map([['a', 1], ['b', 20]]), console.log) // Map
forEach(new Set([4, 12, 89]), console.log) // Set
forEach(new Set([4, 12, 89]).keys(), console.log) // Iterator

12 — Map Anything

My favorite Array methods are .from, .some and .reduce. You can do anything with these so I used the .from to allow me to map anything I want as well with a simple utility function.

const handler = n => n + 10;map([1, 2, 3], handler) // array
map('123', handler) // string
map({a: 1, b: 3, c: 4}, handler) // object
map(new Map([['a', 1], ['b', 20]]), handler) // Map
map(new Set([4, 12, 89]), handler) // Set
map(new Set([4, 12, 89]).keys(), handler) // Iterator

11 — Filter anything

Javascript Array comes with the “filter” method and what I often feel the need for is to filter things out of other data structures that are not arrays. So I created this based on the forEach you saw above, and it inherits the ability to filter from any object or iterable list-like objects. It always returns a new array containing only the things you want.

Code on Github
const arr = [2, 4, 7, 13, 89];filter(arr, (n) => n > 7) // returns [ 13, 89 ]

12 — Fixed Size Array

Javascript Arrays are not Arrays by definition but Javascript has typed arrays that follow the array definition. You can define a size for them but that won’t stop you from adding more or remove items dynamically. If you feel the need to have that restriction then you need this snippet.

Code on Github
const arr1 = createFixedSizeArray(10, 2, 3, 4);
const arr2 = createFixedSizeArray(3);
arr1[9] = 20; // has no effect
arr1.push(10) // throws TypeError: Cannot add property...
arr1.pop() // throws TypeError: Cannot delete property ...
arr2[1] = 12; // sets the value since index one slot exists
console.log(arr1); // prints [ 10, 2, 3, 4 ]
console.log(arr2); // prints [ undefined, 12, undefined ]

13 — Capitalize Words

CSS has the ability to capitalize text in many different ways but to do the same in Javascript you need something of your own. This small function gives you this power.

Code on Github
capitalize("My dog ate my homework") 
// returns 'My Dog Ate My Homework'

12 — File Uploader

I used a version of this snippet on my custom multifile resumable uploader video which you can watch for even more details but this simple snippet allows you to upload any data type to any provided server endpoint URL. It lets you listen to the upload progress as well but if you want to learn more about resuming and pausing upload watch my video on the topic.

Code on Github
postData('http://localhost:1234/upload', {name: 'John Doe'})
.then(res => {
console.log('end', res)
});
const onProgress = event => {
console.log(event.total, event,loaded);
}
postData('http://localhost:1234/upload', myFile, {onProgress})

13 — Class private properties

Javascript has its own way to create class private members, but it does not get the love it deserves from the community — it has a weird syntax. If you don't like the class built-in way to declare private members you can use the power of closure, scope, and IIFE to create private things.

14 — Abstract class

An abstract class is a class that can only be extended and not instantiated directly. It is useful to create classes that will serve as templates for others or to group common stuff for similar other classes. A good example of its usage is the Item class in my File System video.

This trick works by checking the constructor name. If it is the same as the class where you are checking it is because it is being initialized, otherwise, extended.

15 — Find Average

Need to find the average of a group of numbers? This is how you do it using the reduce Array method.

Code on Github

16 — Group Data by key

Similarly to key data by a specific key you saw above, we can make a tiny change to let us group similar data by using the Array reduce method. This snippet is awesome to help you collect similar data from big lists. If you are using react, consider using the flatlist-react module which has a grouping option that works great to render lists already grouped.

Code on Github
const people = [
{firstName: 'John', lastName: 'Doe'},
{firstName: 'Peter', lastName: 'Carter'},
{firstName: 'Jane', lastName: 'Sigfield'},
{firstName: 'Jonathan', lastName: 'Sigfield'},
{firstName: 'Alice', lastName: 'Doe'},
{firstName: 'Carlos', lastName: 'Carter'},
{firstName: 'Bruno', lastName: 'Sigfield'},
{firstName: 'Before', lastName: 'Semicolon'}
];
groupBy(people, 'lastName')
/* outputs
{
Doe: [
{ firstName: 'John', lastName: 'Doe' },
{ firstName: 'Alice', lastName: 'Doe' }
],
Carter: [
{ firstName: 'Peter', lastName: 'Carter' },
{ firstName: 'Carlos', lastName: 'Carter' }
],
Sigfield: [
{ firstName: 'Jane', lastName: 'Sigfield' },
{ firstName: 'Jonathan', lastName: 'Sigfield' },
{ firstName: 'Bruno', lastName: 'Sigfield' }
],
Semicolon: [ { firstName: 'Before', lastName: 'Semicolon' } ]
}

*/

19 — Shuffle an array

Shuffling is nice when you want to randomize things especially if you are building games or want to simulate a real-world scenario where you get things in a nonspecific order. It can also be a good way to test some code. This snippet is based on the Fisher-Yates shuffle algorithm,

20 — Debounce

Debouncing things ensures that in a specific interval only a single thing happens. For example, you have a button that when clicked it calls the API with a request. In case a user repeatedly clicks the button it means one request for every click but if you denounce it means that once they stop the click and wait a certain time pass then the request is made.

P.S: Debounce function can be used with anything.

Code on Github
const btn = document.querySelector('button');
const clickHandler = event => {
console.log(event.target)
}
btn.addEventListener('click', debounce(1000, clickHandler));

21 — Handle Event Once

In case you are listening to events but only want to react to them once, this snippet will do the trick.

Code on Gtihub
const btn = document.querySelector("button");btn.addEventListener("click", once(console.log));

22 — Handle Event until

Similar to the “once” snippet above, you can make some alterations that make you respond to an event only until a condition is met. The below example handles click on a button incrementing the number until it reaches 6 then stops.

Code on Github
const btn = document.querySelector("button");const handler = e => {
const n = Number(e.currentTarget.textContent);
e.currentTarget.textContent = n + 1;
}
const checker = e => Number(e.currentTarget.textContent) >= 5;btn.addEventListener("click", until(handler, checker));

23 — Observe DOM element

This simple snippet is based on the MutationObserver API and it is just an abstraction/facade with some simple tricks to handle the changes. It detects when an element attribute or content changes. It does not detect things like offsetWidth, height changes.

Code on Github
const btn = document.querySelector('button');observeElement(btn, console.log);btn.style.display = 'block';
/* triggers
{
type: "attributes",
oldValue: null,
newValue: "display: block;"
}
*/
btn.innerHTML = 'another text <span>label</span> after';
/* triggers
{
type: "content",
oldValue: null,
newValue: ["another text ", span, " after"]
}
*/

24 —Simple Observable (like RxJs)

You dont need to install RxJs to do observables. You definitely need it for more complex stuff but for simple observables, you can do this.

Learn More Design Patterns Like This here

Code on Github
const obs = new Observable((observer) => {
observer.next(10);
observer.next(20);
observer.complete();
// gets ignored since its complete
observer.error(new Error());
})
obs.subscribe({
next(value) {
console.log(value); // prints 10, 20
}
});
obs.unsubscribe();// never executes
obs.subscribe((value) => {
console.log('next', value);
});

25 — Extend DOM element with data

By leveraging the power of WeakMap and the wish to extend some type of objects like the DOM Element with some data or capabilities this is your snippet. It lets you add new capabilities to any built-in or third-party libraries without changing them directly.

I used a version of this during my File System implementation video to connect files system data with DOM Elements for easier manipulation.

If powered up with Proxy, this snippet becomes even more powerful, you can learn about that in this other article.

Code on Github
let btn = extendObject(document.querySelector('button'));
let array = extendObject([1, 2, 100]);
// extends API with "position"
btn.set('position', (() => btn.obj.getBoundingClientRect())());
btn.get('position')
// {x: 8, y: 8, width: 34.53125, height: 21, top: 8, …}
// Add ability to get last item to array
array.set('lastItem', (() => array.obj.slice(-1)[0])());
array.get('lastItem')
// 100

Conclusion

Javascript is full of tricks and as a Javascript Developer, you almost feel like a Magician. The goal is to continue learning and be thirsty for knowledge. Learning Javascript is a fun and interesting journey so let me help you by welcoming you to Before Semicolon.

Youtube Channel: Before Semicolon
Website: beforesemicolon.com

Blog & YouTube Channel for Web, UI & Software Development - beforesemicolon.comyoutube.com/c/BeforeSemicolon

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store