You can easily support my projects and me via Github sponsors system! You can follow this link for sponsorship https://github.com/sponsors/barbarbar338
In this post, I'm going to show you 10 awesome JavaScript tips & tricks that I've learned from over 10 years of experience to make your life easier. And it will help you become a better developer. So if you're interested, keep reading.
function calculate(...numbers) {
const data = numbers.reduce((rev, curr) => prev + curr, 0);
return data;
}
const data = calculate(2, 3, 6, 1);
console.log(data); // 12
Be a little more descriptive when naming your variables. In the example above, of course, we can see at a glance that the "data" variable is the sum of numbers, but suppose this "data" nomenclature occurs in more than one place in a larger project. Everything is mixed up!
Use meaningful prefixes when naming your variables:
get
prefix to the name of this function. For example getUser()
set
or update
. For example updateUser()
is
, should
, can
to the beginning. For example canSpeak = true
In short, people should understand what your named variables mean in one reading.
function savePerson({ id, name, favourites }) {
// save person
}
const person = {
id: 1,
name: "Barış",
favourites: [ "coffee", "pasta", "pizza" ],
}
savePerson(person);
Passing arguments as objects in functions is a logical move in many ways:
Below is an example of bad use of arguments.
function savePerson(id, name, favourites) {
// save person
}
const person = {
id: 1,
name: "Barış",
favourites: [ "coffee", "pasta", "pizza" ],
}
savePerson(person.id, person.name, person.favourites);
As you can see, in this example we already have an object as a whole, but we need to pass all the elements of this object as arguments one by one.
function hardOne(number) {
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/, ".");
}
function easyOne(number) {
return new Intl.NumberFormat().format(number);
}
console.log(hardOne(23476283)); // 23.476.283
console.log(easyOne(23476283)); // 23.476.283
JavaScript offers you quite a lot of features. Using these built-in features instead of creating a new function immediately will save you time and allow you to focus on your main project faster. When looking for a solution to your problem, you can use existing functions instead of creating a new function.
const array = [ 1, 1, 2, 3, true, true, "Barış", false, "Barış" ];
const filtered = [ ...new Set(array) ];
console.log(filtered); // [ 1, 2, 3, true, "Barış", false ]
This trick is pretty simple. Suppose I have a string containing numbers, strings and booleans. And I want to make sure there are no duplicate items in this array. I can create a simple Set for this and convert it to an array with the spread operator.
const factory = (function* generator() {
let id = 0;
while (true) {
yield id++;
}
})();
function nextID() {
return factory.next().value;
}
console.log(nextID()); // 1
console.log(nextID()); // 2
console.log(nextID()); // 3
Generators introduced with ES6 are a very useful feature that allows us to create not similar repetitive sequences.
If you don't know what generators are, they are functions that employ lazy evaluation by making use of the yield keyword to process and return data, on-demand.
It may look like generator functions will burn CPU cycles in an infinite loop, however, generators describe a state machine, allowing transitions to forward states to occur through provided code (through subsequent yields). These transitions occur on-demand whenever the next method is called, hence the term lazy evaluation!
With this trick, you no longer have to rely on global/class-scoped variables to remember the state!
function myPromise(ms) {
return new Promise((resolve) => {
setTimeout(() => resolve(ms), ms);
});
}
const promiseOne = myPromise(500);
const promiseTwo = myPromise(5710);
const promiseThree = myPromise(1350);
Promise
.all([ promiseOne, promiseTwo, promiseThree ])
.then((result) => {
console.log("Result of promiseOne:", result[0]); // Result of promiseOne: 500
console.log("Result of promiseTwo:", result[1]); // Result of promiseTwo: 5710
console.log("Result of promiseThree:", result[2]); // Result of promiseThree: 1350
});
If you need to wait for multiple asynchronous processes to finish before performing another action, do not wait for them one at a time. You can use the Promise.all(promiseLike[])
method to run all asynchronous operations at the same time and continue your operation after they are all finished.
const person = {
id: 1,
name: "Barış",
favourites: [ "coffee", "pasta", "pizza" ],
}
console.log(person);
/*
{id:1,name:"Barış",favourites:["coffee","pasta","pizza"]}
*/
console.log(JSON.stringify(person, null, 4));
/*
{
"id": 1,
"name": "Barış",
"favourites": [ "coffee", "pasta", "pizza" ]
}
*/
JSON.stringify(object, replacer, indent)
A simple yet very effective function for exporting readable JSON by supplying the amount of spaces to use for indentation in the third parameter.
The second parameter is the replacer and it can either be a function which controls the stringify-ing process, or it can be an array, in which case it indicates the name of the properties that should be included in the stringified output.
const person = {
id: 1,
name: "Barış",
favourites: [ "coffee", "pasta", "pizza" ],
introduce: () => `Hello, my name is ${person.name}`,
}
console.log(person.introduce()); // Hello, my name is Barış
console.log(person.notExistingMethod()); // ERROR!!!
console.log(person.notExistingMethod?.()); // undefined
With optional chaining being supported in most browsers, it is now easier to parse complex objects.
Previously, developers would resort to using either short-circuits or nested if statements in which they would compare against undefined.
Now, it is even easier (and cleaner!) to accomplish the same validation with the optional chaining operator.
Even better, you can even use optional chaining with expressions using bracket notation, or, if you have a deeply nested object, you can stack optional chaining operators to check for deeper properties.
import { generator } from "./idGenerator.js"
const user = {
id: generator.next(),
name: "Barış",
type: "premium",
}
const post = {
id: generator.next(),
title: "My awesome post!",
author: user,
}
Do not create the functions just to serve a purpose, try to handle multiple tasks with a single function. You don't need to create a special function for everything you need to do. Just use the old one.
console.time("myTimer");
const factory = (function* generator() {
let id = 0;
while (true) {
yield id++;
}
})();
let id = 0;
for (let i = 0; i < 1e6; i++) {
id = factory.next().value;
}
console.timeEnd("myTimer"); // myTimer: 27.902ms
A priceless function for developers seeking to deliver high-performance code, the time method takes a timer name as parameter and expects to be met with a call to timeEnd in which the same timer name is supplied.
The timeEnd method prints the elapsed time in milliseconds between the two function calls and it allows programmers to quickly observe the bottlenecks of their code and refactor with ease.
This approach is much better than calculating the elapsed execution time manually, as it is built-in and widely supported across modern browsers.
Thank you for taking your precious time to read this post. If you want to learn more JavaScript tips & tricks, I recommend you to visit my blog often.