Javascript tips

Always Have A Reference Guide Handy

When you want to learn JavaScript properly, it is a good idea to have a comprehensive reference guide open nearby. A good reference guide is the BitDegree's JavaScript reference. It covers pretty much everything you will ever need to know, and it provides a range of JavaScript examples that you can use to help you understand difficult concepts. It even covers outdated syntax and conventions that you might come across if you are working with old JavaScript code.

Find People To Learn JavaScript With

Learning how to program with JavaScript can be a lonely, boring exercise if you try and do it alone. One of the best ways to take your journey from novice to master JavaScript programmer - is to find like-minded people and learn alongside them. Studying with other people can be very rewarding. If you would like to find other like-minded people who are also learning how to code, start your search on Facebook. Look for 'programming', 'coding', or 'web development' groups in your area. If there isn't one, think about starting one! Alternatively, head over to Meetup.com and search for groups in your local area. If you live in or near a city or major population center, you will find that there is probably already some sort of existing meetup groups for other people who are trying to learn JavaScript, web development, and other types of coding. Join one, head down to their next event, and start connecting with your fellow novice programmers!

Make Use Of Different Types Of Resources

When you are learning something as difficult as programming, it is a good idea to make use of as many different resources as you can. Some of the best resources for people learning how to code with JavaScript include:

  • Online videos - If you are looking for a more in-depth explanation of a difficult concept or of something that you can't quite get your head around, head over to YouTube. You will almost certainly find a video that clearly explains things, allowing you to gain a deeper understanding of the concept in question.
  • Reference guides - As noted above, reference guides are essential when it comes to learning and using any programming language.
  • Other people - There are hundreds of high-quality, active coding forums and chat rooms on the internet. You would be stupid not to take your questions to them, as you will almost certainly find someone who can help you with anything you're struggling with.
  • Online courses - If you aren't already enrolled in a free or low-cost online coding course, then now is your chance! Head over and explore some of the courses on the BitDegree platform and learn JavaScript in no-time. It can be very difficult to start learning a programming language like JavaScript. However, things will be a lot simpler if you make use of the full range of resources available to you.

Named Callback Functions

Anonymous functions can be really useful - they can be declared when and where you want, and are great if you only need the function as a one-off.

let people = [
  {
    id: 1,
    firstName: 'Sam',
    lastName: 'Walpole',
  },
  ...
];

let viewModels = people.map(p => ({
  id: p.id,
  name: `${p.firstName} ${p.lastName}`,
}));
// viewModels = [{ id: 1, name: 'Sam Walpole' }]

However, since the function has no name, you are leaving it up to future developers to work out what the code inside your callback function does - that's ok here, but in a longer, more complex functions it may waste unnecessary time. By declaring the function first as a named function, you instantly make the code more readable and give future developers some clues as to the intent of the function.

let people = [
  {
    id: 1,
    firstName: 'Sam',
    lastName: 'Walpole',
  },
  ...
];

let toViewModel = p => ({
  id: p.id,
  name: `${p.firstName} ${p.lastName}`,
});

let viewModels = people.map(toViewModel);
// viewModels = [{ id: 1, name: 'Sam Walpole' }]

Optional Chaining & Nullish Coalescing Operator

Short circuit evaluation and assignment is so common that new more concise syntax is being added in to JavaScript to achieve the same aim. These are the optional chaining and nullish coalescing operators. I have decided to include both short circuiting and optional chaining/null coalescing since, at the time of writing, the latter are newer features and may not be fully compatible with older browsers. The optional chaining operator (?.) allows you to dive into objects without explicitly having to check if the object is not null. If the object is null, then the expression will just return undefined instead of throwing an error. For example, with optional chaining, the logIfAdult function from above can be rewritten as:

function logIfAdult(person) {
  if(person?.age >= 18) {
    console.log("Person is an adult");
  }
}

The nullish coalescing operator (??) is used to return a default value if the value on the left-hand side of the expression is null. In this way, it replaces the functionality of the OR operator in the logName function above:

function logName(person) {
  let name = person?.name ?? 'Default Name';
  console.log(name);
}

Short Circuit Evaluation & Assignment

The JavaScript logical operators, AND (&&) and OR (||) are known as short circuit operators because they only evaluate the expression as far as necessary in order to determine the result of the boolean expression. For example, AND requires that both sides of the expression evaluate to true. Therefore, if the left-hand side of the expression evaluates to false, it does not bother to check the right-hand side as it would be a waste of time. Similarly, OR requires that only one side off the expression evaluates to true. Therefore, if the left-hand side evaluates to true, it doesn't bother to check the right-hand side. This short circuiting can be useful for adding some safety to expressions involving objects. For example, consider the following function:

function logIfAdult(person) {
  if(person.age >= 18) {
    console.log("Person is an adult");
  }
}

The problem with this implementation is that you cannot guarantee that the person object is not null. If you run this function with a null person, you will get the following error: Uncaught TypeError: Cannot read property 'age' of null. Thanks to short circuit evaluation, we can add some safety like this:

function logIfAdult(person) {
  if(person && person.age >= 18) {
    console.log("Person is an adult");
  }
}

This is because, if person is null it will evaluate to false (this is because null is a "falsey" value, if this concept is new to you, please read this article too), and the whole expression will short circuit. Only if person is not null will the expression move on to check the right-hand side of the expression, at which point we know it is safe to check and we wont get any errors. We can exploit this short circuiting when assigning variables too. For example, consider the following function:

function logName(person) {
  let name = person && person.name;
  console.log(name);
}

logName({ name: 'Sam' });
// logs 'Sam'

logName(null)
// logs 'null'

What is happening here? Well in the first example, we pass the function a valid person object. Because the person object is not null, the AND operator moves over to the right-hand side of the expression, and assigns the value of person.name to the name variable. In the second example, person is null so the expression short circuits and returns null to the name variable. We can extend this further to log a default name instead of just null. This time we use the OR operator, so we will only use the default value if the person object is null.

function logName(person) {
  let name = person && person.name || 'Default Name';
  console.log(name);
}

logName({ name: 'Sam' });
// logs 'Sam'

logName(null)
// logs 'Default Name'

Destructuring Assignment

Destructuring assignment allows one or more object properties to be assigned to variables in a single expression. The created variable will have the same name as the property.

let myObj = {
  id: 1,
  name: 'My Object'
};

// without destructuring assignment
let id = myObj.id;
let name = myObj.name; 
// id = 1, name = 'My Object'

// with destructuring assignment
let { id, name } = myObj;
// id = 1, name = 'My Object'

This is most useful when you know that you need to use multiple properties from an object, you need to use the same property multiple times, or the property the you wish to use is deeply nested in that object. In all these cases, using destructuring assignment saves you from all the clutter of getting the object properties through chaining and makes your code more concise and easier to read. For example, I have recently been working a lot with Leaflet, a Javascript framework for building interactive maps. It is highly customisable and allows you to assign your own properties to different markers on the map. However, accessing these properties can get somewhat messy - we can clean this up with destructuring assignment.

// without destructuring assignment
function onEachFeature (feature, layer) {
  if (feature.properties.hasPopup) {
    let popupContent = `<a href="/feature/${feature.properties.id}">${feature.properties.name}</a>`;
    layer.bindPopup(popupContent);
  }
}

// with destructuring assignment
function onEachFeature (feature, layer) {
  let { hasPopup, id, name } = feature.properties;

  if (hasPopup) {
    let popupContent = `<a href="/feature/${id}">${name}</a>`;
    layer.bindPopup(popupContent);
  }
}

We may have added an additional line of code, but I believe this makes it much clearer and easier to read the intention of this function now. It is also possible to destructure arrays, which allows you to assign one or more elements in that array to variables. However, I do not personally find myself using this syntax often so I wont cover it any further here. If you wish to learn more, please see the MDN reference. Finally, if you are using a function that has an object as a parameter, it is possible to destructure that object within the parameter list. This saves you the effort of having to explicitly declare the variables yourself, and makes it clear which properties are required by the function.

function logPerson(person) {
  let { name, age } = options;

  console.log(`${name} is ${age} years old`);
}

function logPerson({ name, age }) {
  console.log(`${name} is ${age} years old`);
}

Tips to note further

Quick Powers The ** operator returns the result of the first variable to the power of the second variable.

/* Quick Powers */
10 ** 10; // 100

/* Default approach */
Math.pow(10, 10); //100

To repeat a string multiple times

/* Default approach */

let name = 'x'; 
for(let i = 0; i < 6; i ++) { 
  name += name; 
} 
console.log(name); // x x x x x x

/* using repeat() */

var x = "x".repeat(6);

console.log(x);

// x x x x x x

Final tip is to use Semicolons at the end of each statements to improve readability.

Objects

Object Destructring Using destructuring we can able to directly get the objects.

/* Default approach */

const user = {
status:'Active';
ratings:'5';
}
const rating = user.ratings;
console.log(rating);

/* Default approach */

const user = { status:'Active'; ratings:'5'; }
const  { status, ratings } = user;
console.log(ratings);

Object.entries() object.entries() method returns an array of a given object's own enumerable string-keyed property [key, value] pairs.

const userOne = {
  id: '101',
};

for (const [key, value] of Object.entries(userOne)) {
  console.log(`${key}: ${value}`);
}

// Result:  id: 101

Object.values() object.values() method returns an array of a given object's own enumerable property values, in the same order as that provided.

const userOne = {
  id: '101',
};

console.log(Object.values(userOne));

// Result: ['101']

Arrays

To Get an Array of Unique Value set() is used to get an array of unique values.

const studentId = [101, 101, 102, 103, 105, 105, 101];
const uniqueId = [...new Set(studentId)];
console.log(uniqueId); 

// Result: [101, 102, 103, 105]

To Split a String into an Array

const string = "Form"
const splitValue = [...string] // the spread operator ...
console.log(splitValue);

// Result: ["F", "o", "r", "m"]

To Find Max and Min in an array

var  values = [25,100,30,55,15,80,200,360,70,40,45,130]; 
var maxValue = Math.max.apply(Math, values); 
var minValue = Math.min.apply(Math, values);

Truncate an array This method allows you to truncate an array without using splice() .

/* Our approach */

let names = ['Ram', 'Sita', 'Nithya', 'Varun ', 'Devi']
names.length(3);
console.log(names); 

// Result: ['Ram', 'Sita', 'Nithya']

/* Using slice() */

let names = ['Ram', 'Sita', 'Nithya', 'Varun ', 'Devi']
names.slice(0,3);
console.log(names); 

// Result: ['Ram', 'Sita', 'Nithya']

To Cast values in an array

let values=['201','202','203,'204','205]
values = values.map(Number) 

// Result: [ 201, 202, 203, 204, 205 ]