Q101.

What primitive types does JavaScript support?

JavaScript, a high-level, interpreted programming language, categorizes data into two main groups: primitive types and object types. Primitive values are immutable, meaning their value cannot be changed after creation. Understanding these fundamental types is crucial for writing effective JavaScript code. There are seven primitive data types supported by JavaScript.

The Seven JavaScript Primitive Types

Below is a detailed explanation of each of the seven primitive data types available in JavaScript, along with their characteristics and common use cases.

1. String

Represents textual data. Strings are immutable sequences of Unicode characters. They can be created using single quotes (''), double quotes (" "), or backticks (``) for template literals, which allow for embedded expressions.

2. Number

Represents both integer and floating-point numbers. JavaScript uses double-precision 64-bit binary format IEEE 754 for numbers. This type includes special values like Infinity (positive infinity), -Infinity (negative infinity), and NaN (Not-a-Number), which represents an invalid or unrepresentable number.

3. BigInt

Introduced in ES2020, BigInt is a primitive type that can represent integers with arbitrary precision. This means BigInt numbers can store values larger than 2^53 - 1, which is the maximum safe integer for the Number type. BigInt numbers are created by appending n to the end of an integer literal (e.g., 10n).

4. Boolean

Represents a logical entity and can have only two values: true or false. These are fundamental for conditional logic, control flow statements, and expressing truthiness or falsiness in operations.

5. Undefined

A variable that has been declared but has not yet been assigned a value is undefined. It signifies the absence of a value, often indicating that a variable lacks a meaningful assignment or a function parameter was not provided.

6. Symbol

Introduced in ES6 (ECMAScript 2015), a Symbol is a unique and immutable data type. Symbols are often used to create unique object property keys that prevent name clashes in objects, especially when mixing code from different libraries or modules.

7. Null

Represents the intentional absence of any object value. null is a primitive value and is often explicitly assigned to a variable or property to indicate that it has no value or points to nothing. It's important to note that typeof null returns "object", which is a historical quirk in JavaScript.

These seven primitive types are the foundational building blocks for data manipulation in JavaScript. They are distinct from object types, which are mutable and more complex, allowing for properties and methods.

Q102.

Is null a primitive type in JavaScript?

Yes, in JavaScript, `null` is indeed considered a primitive type. It represents the intentional absence of any object value and is one of the seven primitive data types alongside undefined, boolean, number, bigint, string, and symbol.

Understanding Primitive Types in JavaScript

Primitive types are fundamental, immutable values that are not objects and have no methods of their own. They form the basic building blocks of data in JavaScript. There are currently seven primitive types:

  • undefined
  • boolean
  • number
  • bigint
  • string
  • symbol
  • null

null is a special primitive value that signifies the intentional absence of any object value. It is often used to explicitly indicate that a variable has no value or points to no object.

The 'typeof null' Anomaly

A common point of confusion arises because the typeof operator, when applied to null, returns 'object'. This is a widely acknowledged historical bug in JavaScript that dates back to its very first implementation. It was decided not to fix this behavior to maintain backward compatibility, despite null unequivocally being a primitive value, not an object.

javascript
console.log(typeof null); // Outputs: 'object'
console.log(null === null); // Outputs: true
console.log(null == undefined); // Outputs: true (loose equality)
console.log(null === undefined); // Outputs: false (strict equality)
Q103.

What is the result of typeof null?

Understanding the `typeof` operator and its behavior with `null`.

Understanding the `typeof` Operator

The typeof operator in JavaScript is used to determine the type of a given operand. It returns a string indicating the data type of the unevaluated operand.

The Result of `typeof null`

javascript
console.log(typeof null);

When you execute typeof null in JavaScript, the returned value is "object".

Why `typeof null` is 'object'

This behavior is a well-known historical bug in JavaScript, dating back to its first implementation. In JavaScript, internal values are represented by a type tag and a value. For objects, the type tag is 0. Null was represented as the NULL pointer (0x00), and it also had 0 as its type tag. Consequently, typeof incorrectly identified null as an object.

Despite being a bug, fixing it would break a lot of existing web code, so it remains a feature of the language. It's important to remember this specific behavior when working with typeof and checking for null values, often requiring an explicit === null check.

Q104.

What is the difference between let, const and var?

In JavaScript, `var`, `let`, and `const` are keywords used for declaring variables. While they all serve this fundamental purpose, they differ significantly in terms of scope, hoisting, and mutability, impacting how variables behave in your code. Understanding these differences is crucial for writing robust and predictable JavaScript applications.

`var` Keyword

The var keyword was the original way to declare variables in JavaScript prior to ES6 (ECMAScript 2015). Variables declared with var are function-scoped or globally-scoped, meaning they are accessible throughout the entire function in which they are declared, or globally if declared outside any function.

var variables are hoisted to the top of their scope and initialized with undefined. They can be re-declared and re-assigned within the same scope without error, which can sometimes lead to unexpected behavior and bugs, especially in larger codebases.

javascript
function exampleVar() {
  console.log(myVar); // undefined (hoisted, but not yet assigned)
  var myVar = 10;
  console.log(myVar); // 10

  if (true) {
    var myVar = 20; // Re-declared and re-assigned within the same function scope
    console.log(myVar); // 20
  }
  console.log(myVar); // 20 (still accessible and modified across the function)
}
exampleVar();

var globalVar = 5;
var globalVar = 15; // Allowed re-declaration in global scope
console.log(globalVar); // 15

`let` Keyword

Introduced in ES6, let allows you to declare block-scoped variables. This means a variable declared with let is only accessible within the block (curly braces {}) where it is defined, as well as any nested blocks. This provides more control over variable visibility compared to var.

Like var, let variables are hoisted, but they are not initialized. Instead, they enter a 'temporal dead zone' from the start of the block until their declaration is processed. Accessing a let variable before its declaration results in a ReferenceError. let variables can be re-assigned but cannot be re-declared within the same scope, preventing common mistakes seen with var.

javascript
function exampleLet() {
  // console.log(myLet); // ReferenceError: Cannot access 'myLet' before initialization (Temporal Dead Zone)
  let myLet = 10;
  console.log(myLet); // 10

  if (true) {
    let myLet = 20; // This is a new, separate variable, block-scoped to the if block
    console.log(myLet); // 20
  }
  console.log(myLet); // 10 (the outer myLet is untouched)

  myLet = 30; // Re-assignment is allowed for the outer myLet
  console.log(myLet); // 30

  // let myLet = 40; // SyntaxError: Identifier 'myLet' has already been declared (in this scope)
}
exampleLet();

`const` Keyword

const, also introduced in ES6, is used to declare block-scoped constants. Similar to let, const variables are block-scoped and exist within a temporal dead zone until their declaration. The main characteristic of const is that it creates a read-only reference to a value.

A const variable must be initialized at the time of declaration and cannot be re-assigned. For primitive values (numbers, strings, booleans), this means the value itself cannot change. For objects and arrays, the reference to the object/array cannot change, but the properties or elements of the object/array can still be modified, as the reference itself remains constant.

javascript
function exampleConst() {
  // const myConst; // SyntaxError: Missing initializer in const declaration
  const myConst = 10;
  console.log(myConst); // 10

  // myConst = 20; // TypeError: Assignment to constant variable.

  if (true) {
    const myConst = 30; // New block-scoped variable
    console.log(myConst); // 30
  }
  console.log(myConst); // 10 (the outer myConst is untouched)

  const myObject = { name: 'Alice', age: 30 };
  myObject.name = 'Bob'; // Allowed: property of the object can be modified
  myObject.age = 31;
  console.log(myObject); // { name: 'Bob', age: 31 }

  // myObject = { name: 'Charlie' }; // TypeError: Assignment to constant variable. (reference cannot change)
}
exampleConst();

Summary of Differences

Feature`var``let``const`
ScopeFunction-scoped or Global-scopedBlock-scopedBlock-scoped
HoistingYes, initialized with `undefined`Yes, but in Temporal Dead ZoneYes, but in Temporal Dead Zone
Re-declarationAllowedNot AllowedNot Allowed
Re-assignmentAllowedAllowedNot Allowed (for the reference)
InitializationOptionalOptionalRequired at declaration

Best Practices

In modern JavaScript, it is generally recommended to avoid var entirely due to its confusing scope and hoisting behavior. Use const by default for any variable that does not need to be re-assigned. If you anticipate that a variable's value will need to change, then use let. This approach enhances code readability, predictability, and helps prevent common programming errors by ensuring variables have the narrowest possible scope and mutability as intended.