Skip to main content

Command Palette

Search for a command to run...

JavaScript Fundamentals That Finally Make Sense

A beginner-friendly guide to template literals, truthy and falsy values, type conversion, and implicit coercion.

Updated
8 min readView as Markdown
JavaScript Fundamentals That Finally Make Sense
M
Software Developer

Template literals (Template strings)

Template literals are literals delimited (determine the limit or boundary) with back-ticks `` (define string here) characters for declaring strings, allowing for multi-line stringsstring interpolation with embedded expressions.

let name = 'Ayan'; 
console.log(`Hello ${name}`); // Hello Ayan
💡
Embedding variables: Template literals like Hello ${name} insert variable values directly into strings, producing output such as hello Ayan.

Cleaner concatenation: They avoid using +, making string creation more readable and easier to write.

Template literals take all the number values and converts them into string.

Truthy and Falsy values

💡
Those values can be called as true or false in Boolean context.

falsy values

falsy value is a value that is considered false when encountered in a Boolean context.

💡
falsy values are values that are not exactly false, but will become false when we try to convert them into a boolean.

JavaScript uses type coversion (explicit conversion) to coerce (implicit convert) any value to a Boolean in contexts that require it, such as conditional and loops.

false, undefined, NaN, null, "", 0, 0n, -0

truthy values

In JavaScript a truthy value is a value that is considered true when encountered in a Boolean context.

true, 1, "Ayan"

Except falsy all values are truthy.

Type coercion

Type coercion is the automatic or implicit conversion of values from one data type to another (such as strings to numbers).

const value1 = "5";
const value2 = 9;
let sum = value1 + value2;

console.log(sum); // 59
💡
It happens whenever an operator is dealing with two values that have different type, behind the scene JavaScript convert one of the values to match the other value.

Explanation

JavaScript has coerced the 9 from a number into a string and then concatenated the two values together, resulting in a string of 59.

JavaScript had a choice between a string or a number and decided to use a string.

Why? Because it’s defined in it’s engine.

The compiler could have coerced the 5 into a number and returned a sum of 14, but it did not.

To return this result, you'd have to explicitly convert the 5 to a number using the Number() method:

console.log(Number("9" + 5); // 14

How Type Coercion Works?

In JavaScript, type coercion mainly occurs in the three ways:

String Coercion

It occurs when the string is combined with the non-string using (+). JavaScript converts numbers and booleans into strings before concatenation.

console.log("5" + 2); //52
console.log("5" + true); //5true
  • The number 2 is coerced to a string and then concatenated with the string "5", resulting in "52".

  • The boolean true is coerced into the string "true", and the two strings are concatenated.

Number Coercion

In the number coercion*, JavaScript converts the* string into a number before operating.

console.log("5" - 2); //3
console.log("5" * 2); //10
console.log("10" / "2"); //5
💡
With + operator, JavaScript performs concatenation. Except + operator, JavaScript performs arithmetic operations.

Boolean Coercion

JavaScript treats the truthy / true value as 1 and the falsy / false value as 0.

console.log(Boolean("hello")); //true
console.log(Boolean(0)); //false
console.log(Boolean([])); //true

Non-empty strings are coerced to true, while 0 is coerced to false.

Common Issues of Type Coercion

Comparing Different Data Types

Comparison Operator (==), allows coercion due to which the unexpected conversions occur. To avoid this, we should use the strict equality (===) operator.

console.log(0 == "0"); //true
console.log(0 == false); //true
console.log(" " + 0 == 0); //true

Operations on null and undefined

Null and undefined behave unexpectedly.

console.log(null == undefined); //true
console.log(null === undefined); //false
console.log(null + 1); //1

NaN Comparisons

NaN is not equal to itself*, so checking with* isNaN() is the best way to detect it.

console.log(NaN == NaN); //false
console.log(isNaN(NaN)); //true

Best Practices to Avoid Type Coercion Issues

Use === Instead of ==

When we use strict equality (===), instead of the comparison operator / loose equality (==), it prevents unnecessary types of coercion*.*

console.log(5 === "5"); //false

=== ensures no implicit type conversion occurs and both values must be of the same type.

Use Explicit Conversion

Explicit conversion converts the value manually due to which there are fewer chances of errors in the code.

console.log(Number("123")); //123

This ensures that you're working with the correct type*, reducing the chance of errors during operations.

Avoid False Value Confusion

Always check for null, undefined, or “” empty strings explicitly.

if (value !== null && value !== undefined) {
    console.log("Value exists");
}

This ensures that only non-null and defined values are considered valid.

Use parseInt() and parseFloat() for Number Conversion

console.log(parseInt("42px")); //42
console.log(parseFloat("3.14abc")); //3.14

This will parse the number part of a string, ensuring a valid numeric conversion.

Handle NaN Properly

💡
Use isNaN() to check if a value is NaN instead of comparing it directly.
if (isNaN(value)) {
    console.log("Invalid number");
}

This ensures you're correctly detecting NaN and handling it appropriately.

Type conversion

Manually or explicitly convert the type of a value from one data-type to another.

Original value doesn’t converted.

JavaScript can only convert to three types. we can convert to a number, to a string, or to a boolean.

const inputYear = "1996";
console.log(Number(inputYear), inputYear);

Function

The fundamental building block of real-world JavaScript applications are functions. It’s a reusable piece of code.

function declaration

function logger() {//function-body
  console.log("My name is Ayan");
}
//calling or running or invoking function
logger();

We can pass data into a function. It can return data as well. We can pass parameters to the function, the parameters are like variables that are specific only to this function and they will get defined once we call the function.

These are like placeholders that actually replaced by arguments that passed to the function.

function calcAge1(birthYear) {
  return 2026 - birthYear;
}

const age = calcAge1(2015);
console.log("Ayan is", age, "years old.");

This function is called function declaration.

return statement

  • The return statement is used to send a result back from a function.

  • When return executes, the function stops running at that point.

  • The returned value can be stored in a variable or used directly.

function fruitProcessor(apples, oranges) {//(apples,oranges) are Parameters

  const juice = `Juice with ${apples} apples and ${oranges} oranges.`;
  return juice;
}

const appleJuice = fruitProcessor(2, 0); //(2, 0)--> Arguments
console.log(appleJuice);

const applesOrangesJuice = fruitProcessor(3, 5);
console.log(applesOrangesJuice);

Function expression & declaration

In JavaScript there are different way of writing functions and each type of function, works in a slightly different way.

function declaration / named function

A function that has its own name when declared. It’s easy to reuse and debug because the name shows up in error messages or stack traces.

function calcAge1(birthYear) {
  return 2026 - birthYear;
}

const age = calcAge1(2015);
console.log("Ayan is", age, "years old.");

function expression* / *Anonymous function

An anonymous function is a function defined without an explicit name. It is commonly used as a callback or assigned to a variable. It can be named or anonymous.

const calcAge2 = function (birtYear) {
  //Anonymous function or function expression
  return 2026 - birtYear;
};
const ageAltamash = calcAge2(2005);
console.log("Altamash is", ageAltamash, "years old.");

/*
function (birtYear) {
  return 2026 - birtYear;
}; It's the expression and produces a vlue
*/

Hoisting

Functions in JavaScript just are actually values. function declarations can called before they defined in the code. Internally this happens because of the process hoisting.

(=>) arrow function

An arrow function is simply a special form of function expression that is shorter and therefore faster to write. It was introduced in ES6. They don’t their this binding.

const yearsUntilRetirement = (birtYear, firstName) => {
  const age = 2026 - birtYear;
  const retirement = 60 - age;
  return `${firstName} retires in ${retirement} years.`;
};

const retirementYears = yearsUntilRetirement(1980, "Jacob");
console.log(retirementYears);

this keyword

this refers the current context. It means the object is calling this function.

calling one function from inside another function