Explain the difference between == and ===

  •  We all know that == is equality operator is used to compare two values in JavaScript.
  • === operator is strict equality operator
  • Both == & === are used to compare values in JavaScript. then what is the difference between == and === lets discuss in detail
  • == compares two values by converting them to same data types, 10 == ''10" will be true because string type of 10 converted in to number.
  • === compares two values without converting them to same data type. 10 === "10"
  • Use our JavaScript compiler to test your snippets
== vs === in JavaScript


1.  == ( loose Equality)
  • Checks value equality after type conversion

  • Converts operands to same type before conversion (ex: 10 == '10' here string 10 will be converted in to number) 

2. === Strict equality
  • checks value and type without conversion.
  • return false if types are different.
ScenarioLoose ==)Strict (===)
5 vs. "5truefalse
0 vs. falsetrue false
null vs. undefinedtruefalse
NaN vs NaNfalsefalse
{} vs {}falsefalse


Explanation:

1. 5 == "5" → true(loose)  
   - JavaScript converts "5" (string) to 5 (number) before comparison.  
  5 === "5" → false(strict)  
   - Different types: number vs. string.  

2. 0 == false → true(loose)  
   false is converted to 0, so 0 == 0 is true.  
  0 === false → false(strict)  
   - Number vs. boolean, so different types.  

3. null == undefined → true(loose)  
   - Special case:null andundefined are only loosely equal to each other.  
  null === undefined → false(strict)  
   - Different types:null vs.undefined.  

4. NaN == NaN → false(loose)  
   NaN is  not equal to itselfin JavaScript.  
  NaN === NaN → false(strict)  
   Same reason here: NaN is never equal to anything, including itself.  

5. {} == {} → false(loose)  
   - Objects are compared by **reference**, not by value.  
   - Different objects in memory, so alwaysfalse.  
  {} === {} → false (strict)  
   - Still different object references. 

  • "5" === "5" returns true
Remember these special cases:
  • NaN == NaN will be false even with == operator ,Use Number.isNaN(x) to check for NaN.
  • null == undefined will be true
When to use which operator:
  • always use === as it is recommended way and which avoids unexpected type conversion
  • use == for null/undefined check
  • if (x == null) { ... } // Catches both `null` and `undefined`.

var, let, and const in JavaScript

Decrypt var, let, and const in JavaScript: A Complete Analysis

A JavaScript variable is typically created using one of three keywords: var, let, or const. Each behaves differently in terms of scope, hoisting, and mutability, though they all might function very similarly. This article breaks down the differences between these keywords in simple terms so that you can write cleaner and more secure code

var let const in javascript

1. var: The Old Legacy Variable Declaration

Scope: Function Scope

  • Variables declared with var are function scoped (or globally scoped if defined outside a function).
  • They're accessible from anywhere within the function where they are defined.

Example:

function exampleVar() {
 if (true) {
  var x = 10;
 }
 console.log(x); // 10 (not limited to the block)
};

Hoisting

  • var declarations are hoisted to the top of the containing function and initialized with undefined.
  • This can lead to unexpected behavior if not taken into account.
console.log(y); // undefined (no error)
var y = 5;

Redeclaration and Reassignment

  • var allows redeclaration and reassignment:
var z = 1;
var z = 2; // No error
z = 3;     // Reassignment allowed

Drawbacks

  • No block scoping: Variables leak into blocks like loops or conditionals.
  • Prone to bugs: May cause unintended side effects from hoisting and redeclaration.

2. let: The Modern Block-Scoped Variable

Block-Level Scope

  • let variables are block scoped: they only exist within {} like loops, conditionals, or function bodies.
  • Safer and more predictable than var.

Example:

function exampleLet() {
 if (true) {
  let a = 20;
  console.log(a); // 20
 }
 console.log(a); // ReferenceError: a is not defined
}

Hoisting and the Temporal Dead Zone (TDZ)

  • let declarations are hoisted but not initialized.
  • Accessing them before declaration results in ReferenceError.
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 5;

Reassignment and Redeclaration

  • let allows reassignment but not redeclaration.
let c = 10;
c = 20; // Allowed
let c = 30; // SyntaxError: Identifier 'c' has already been declared

3. const: Constants for Immutable Values

Scope: Like let, Block Scoped

  • Variables created with const are block scoped, meaning they can only be accessed within their defining block.
  • They cannot be reassigned after initialization.

Example:

const PI = 3.14;
PI = 3.14159; // TypeError: Assignment to constant variable

Immutable ≠ Unchangeable Values

  • With const, you cannot reassign values, but you can mutate them.
  • Objects and arrays declared with const can have their properties/methods altered.
const person = { name: "Alice" };
person.name = "Bob"; // Valid
person = { name: "Charlie" }; // TypeError (reassignment not allowed)

Hoisting and the Temporal Dead Zone (TDZ)

  • Similar to let, const declarations are also hoisted and trigger the TDZ.

Key Differences Summary

Feature var let const
Scope Function/Global Block Block
Hoisting Yes (initialized) Yes (not initialized) Yes (not initialized)
Redeclaration Allowed Not allowed Not allowed
Reassignment Allowed Allowed Not allowed
TDZ No Yes Yes

When to Use Each

  1. const (Recommended):

    • For values that shouldn’t be reassigned (e.g., configuration objects, API keys).
    • Used by default unless reassignment is needed.
  2. let:

    • When a variable requires reassignment (e.g., loop counters, state changes).
    • More robust than var with block scope.
  3. var:

    • Rarely needed in modern JavaScript. Use only in legacy projects or specific cases.

Common Mistakes

Slipping into Global Variable Declarations

function badPractice() {
 for (var i = 0; i < 5; i++) { /*... */ }
 console.log(i); // 5 (leaked outside loop)
}

Fix: Use let for block scoping.

Issues Related to TDZ

let greeting = "Hello";
if (true) {
 console.log(greeting); // ReferenceError (TDZ)
 let greeting = "Hi";
}

Fix: Define variables at the top of their scopes.

Misunderstandings of const’s Immutability

const arr = [1, 2];
arr.push(3); // Valid (array contents changed)
arr = [4, 5]; // TypeError (reassignment not allowed)

Best Practices

  1. Use const by default, and let only when reassignment is necessary.
  2. Avoid var , except for maintaining legacy code.
  3. Declare variables at the top to avoid TDZ errors.
  4. Use linters like ESLint to enforce best practices.

Conclusion

Understanding var, let, and const is crucial for writing secure JavaScript. Embracing block scope (let

/const) and immutability (const) reduces bugs and makes your code easier to debug and maintain.

Key takeaways:

  • const prevents reassignment but not mutation.
  • let and const are the modern standard in JavaScript.

how to merge objects in javascript

There are various ways to combine two objects in JavaScript. Whether you want to conduct a shallow or deep merge will determine which technique you use.

merge objects in javascript


1. Shallow Merge (Overwrite Properties)

  • Using Object.assign():

const obj1 = { a: 1, b: 2 };

const obj2 = { b: 3, c: 4 };


const merged = Object.assign({}, obj1, obj2);

// Result: { a: 1, b: 3, c: 4 }

  • Using the Spread Operator (...):

const merged = {...obj1,...obj2 };

// Result: { a: 1, b: 3, c: 4 }

Note: Both methods are shallow merges—nested objects/arrays are all by reference (not cloned). If there are duplicate keys, subsequent properties will overwrite prior ones.

2. Deep Merge (Recursively Combine Nested Properties)

  • Using Lodash:

const merged = _.merge({}, obj1, obj2);

  • Custom Deep Merge Function (Simplified Example):

function deepMerge(target, source) {

for (const key in source) {

if (source[key] instanceof Object && target[key]) {

deepMerge(target[key], source[key]);

} else {

target[key] = source[key];

}

}

return target;

}


const merged = deepMerge({}, { a: { x: 1 } }, { a: { y: 2 } });

// Result: { a: { x: 1, y: 2 } }

Other Considerations

  • Shallow Merge: For simple scenarios, employ Object.assign() or the spread operator.
  • Deep Merge: For greater resilience, use a tool such as Lodash (e.g. _.merge()), which is able to contend with sophisticated structures, including arrays and null values
  • Overwriting Behavior: In situations involving conflict over keys, later objects always win.

Preventdefault vs stoppropagation javascript

 Here is a brand new essay about preventDefault() versus stopPropagation() in Angular. I'll start by comparing how they're used with preventDefault() and stopPropagation. We'll also offer a case study for each method and share some tips.

preventdefault vs stoppropagation javascript angular


1. event.preventDefault() in Angular

  • Purpose: To prevent the default action of a browser event (for example, a submission form or hyperlink).
  • Use in Angular: With Angular’s event binding syntax (event)="handler($event)"
.

Example: Prevent link from navigating:

<a href="https://dangerous.com" (click)="onLinkClick($event)">Dangerous Link</a>
onLinkClick(event: MouseEvent) {
  event.preventDefault(); // Stop navigation
  // Custom logic here (e.g., show a modal instead)
}
  • Scenarios Commonly Encountered in Angular:
    • When using (submit) and <form> to cancel form submission.
    • Shut off the default behaviors of anchor tags, buttons, or form fields.

2. event.stopPropagation() in Angular

  • Purpose: Stop event bubbling/capturing in the DOM tree.
  • Use in Angular: To prevent parent and descendant components from receiving the exact same events.

Example: Don't let a press on a button cause the parent <div> method to fire:

<div (click)="onParentClick()">
  <button (click)="onButtonClick($event)">Click Me</button>
</div>
onButtonClick(event: MouseEvent) {
  event.stopPropagation(); // The mom's onParentClick() will not fire
  // Take care of button click
}
  • Specific Cases:
    • Stop nested components from propagating events.
    • Avoid conflict with other handlers dealing in similar space (e.g., dropdown, modals).

3. Key Differences in Angular

preventDefault() stopPropagation()
Focus Prevent browser from default behavior (e.g., form submit) Prevent DOM event bubbling/capturing
Use Case in Angular Cancel navigation, form submission Parent and child Components surface events in their own spaces
Template Syntax (submit)="onSubmit($event)" (click)="onClick($event)"

4. Using Both Together in Angular

Example: Handle a custom form action without submitting and prevent parent components from interpreting it:

<form (submit)="onFormSubmit($event)">
  <button type="submit">Save</button>
</form>
onFormSubmit(event: Event) {
  event.preventDefault(); // Halt the default form submission
  event.stopPropagation(); // Don't let parent events hear about this
  this.saveData(); // Custom logic here, e.g. http call
}

5. Angular Special Notes

Event Modifiers

Angular does not provide its own event modifiers like Vue's .prevent or .stop. You need to call the method explicitly instead:

<form (submit)="onSubmit($event)"></form>
onSubmit(event: Event) {
  event.preventDefault(); // Manually call
}

Component Communication

  • stopPropagation() only affects DOM events, not Angular's @Output().

Example:

<app-child (customEvent)="onChildEvent()"></app-child>
// ChildComponent
@Output() customEvent = new EventEmitter();
emitEvent() {
  this.customEvent.emit();
  // Whether the parent code listens to DOM event propagation, onChildEvent() will fire
}

Change Detection

  • Neither method affects Angular change detection.
  • Use NgZone or ChangeDetectorRef when events bypass Angular's domain (for example, setTimeout).

6. Angular Best Practices

  1. How to Break Free from Inline Calls: Place your methods right in the constituent, rather than inside the official template:

    <a href="#" (click)="onClick($event)">Link</a>
    <button (click)="onClick($event)">Link</button>
    
  2. For Component Communication, Use EventEmitter : Old-fashioned emit rather than DOM event. Use @Output() Stateless Copy for State Changes: Ensure data is never changed after a call to preventDefault(), to be sure change detection fires.


7. Common Traps

  • Lack of $event: Don’t forget to mention $event in the template:

    <button (click)="onClick">Click</button> ❌ Incorrect
    <button (click)="onClick($event)">Click</button> ✅ Correct
    
  • Too Much stopPropagation(): For highly intricate component trees, it can only create debugging headaches.

In Angular:

  • preventDefault(): Regulate browser defaults (e.g., forms, links).
  • stopPropagation(): Control event flow between some connected DOM elements/components.
  • Use both in tandem to finely manage your event firing and your UI experience.


splice vs slice in javascript

 'splice()' and 'slice()' are two array techniques in JavaScript that are often confused with each other. In order to resolve these ambiguities, we will compare the two methods below step by step.

splice vs slice javascript


1. Creating a Slice: The Simple Version

Purpose

Evaluates only a small part of an array without changing it.

Usage

array.slice(startIndex, endIndex);

Main Points

  • Produces a new array consisting of the elements from startIndex to endIndex (not inclusive).
  • Changes made to the original array are not visible.
  • If indexes are negative, they count from the end.
  • If no arguments are given, then array.slice() makes a shallow copy of the entire array.

Example

const fruits = ['apple', 'banana', 'cherry', 'date'];

const sliced = fruits.slice(1, 3);

console.log(sliced); // ['banana', 'cherry']

console.log(fruits); // ['apple', 'banana', 'cherry', 'date'] (that's how it remained)

2. splice(): Add/Remove Elements from an Array

Purpose

Alters the original array, inserts or deletes elements.

Syntax

array.splice(startIndex, deleteCount, item1, item2,...);

Key Points

  • Changes the original array.
  • Returns an array followed by the removed elements (if any).
  • Deleting, adding or changing elements on the spot are all possible.

Examples

a. Deleting Elements

const numbers = [1, 2, 3, 4, 5];

const removed = numbers.splice(1, 2); // Start removing from position 1 and remove 2 from that

console.log(removed); // [2, 3]

console.log(numbers); // [1, 4, 5]

b. Adding Elements

const colors = ['red', 'blue'];

colors.splice(1, 0, 'green'); // Add 'green' after index 1 without deleting anything

console.log(colors); // ['red', 'green', 'blue']

c. Replacing Elements

const letters = ['a', 'b', 'c'];

letters.splice(1, 1, 'x'); // Replace 'b' with 'x' at index 1

console.log(letters); // ['a', 'x', 'c']

3. The Key Differences

Featureslice()splice()
Mutates OriginalNoYes
Return ValueNew array of extracted elementsArray of removed elements (if any)
Parameters(start, end)(start, deleteCount, items...)
Use CaseCopy a piece of an arrayAdd/remove elements in place

  • Slice Use it when you need to take a part from the array out without changing the original.
  • Example: Generate a copy of an array:
  • const copy = arr.slice();
  • Splice Use it when you need to remove, add, or adjust an array.
  • Example: Update a list dynamically, such as editing a to-do list.

5. Pitfalls of Using These Two Methods

Mixed Parameters Puzzle

  • Slice (1, 3) obtains elements from indices 1 and 2 (excluding index 3).
  • Splice (1, 3) starts at index 1 and removes three elements.

Splice's Mutability

  • Splice() changes the original array, so always make sure you don't need to preserve the original data before using it.

Summary

  • Slice: copy parts of an array without changing the original.
  • Splice: can edit an array directly, deleting, introducing or replacing parts.

5 Simple Ways to Copy an Array in JavaScript

5 Simple Ways to Copy an Array in JavaScript

In JavaScript, there are 5 simple ways to copy an array to another array. Here are some examples and explanations.

5 Simple Ways to Copy an Array in JavaScript


1. Using the Spread Operator (...)

The newest and easiest way (ES6 and above):

const original = [1, 2, 3];
const copy = [...original];
console.log(copy); // [1, 2, 3]

2. Using slice()

A traditional method for making a shallow copy:

const original = ['a', 'b', 'c'];
const copy = original.slice();
console.log(copy); // ['a', 'b', 'c']

3. Using Array.from()

Turns an iterator (like an array) into a new array:

const original = [10, 20, 30];
const copy = Array.from(original);
console.log(copy); // [10, 20, 30]

4. Using concat()

Copies the original array by adding an empty array:

const original = [true, false, true];
const copy = original.concat();
console.log(copy); // [true, false, true]

5. Using map()

Iterates through and returns every item (rare but feasible):

const original = [{ name: 'Alice' }, { name: 'Bob' }];
const copy = original.map(item => item);
console.log(copy); // [{ name: 'Alice' }, { name: 'Bob' }]

Shallow Copy vs. Deep Copy

Shallow Copy

The methods above copy primitive values (numbers, strings), but reference objects (arrays/objects inside an array) still refer to the same memory location as the original.

const original = [{ x: 1 }];
const copy = [...original];
copy[0].x = 99; 
console.log(original[0].x); // 99 😱

Deep Copy

For nested arrays/objects, use:

const deepCopy = JSON.parse(JSON.stringify(original));

Note: This does not work for Date objects, functions, or circular references.

Which Method Should You Use?

Use Spread Operator ([...arr]) or Array.from() → Suitable for most cases.
Need browser support for older code? → Use slice()

.
Need a deep copy? → Use JSON.parse(JSON.stringify(arr)) (with restrictions) or a library like _.cloneDeep() from Lodash.

Common Mistake

🚨 Do not assign arrays directly! This only creates a reference, not a copy.

const original = [1, 2, 3];
const badCopy = original; // Both point to the same array!
badCopy.push(4);
console.log(original); // [1, 2, 3, 4] 😱

Let me know if you need any further improvements! 😊

Javascript versions list

ESMAScript Versions and Features

JavaScript, a programming language that defines the Web, has evolved significantly since its birth in 1995. Starting as a simple scripting tool, it has grown into a diverse and powerful language.

We will use ECMAScript (ES) standards to trace its evolution. This blog post provides an overview of JavaScript versions, their history, and key characteristics, creating a context for modern web development.

1. Introduction: JavaScript and ECMAScript

JavaScript was created by Brendan Eich in 1995 for Netscape Navigator. Later, ECMA International, a standards organization, formalized it under the ECMAScript (ES) specification. While commonly referred to as "JavaScript," ECMAScript represents the standardized version of the language.

Major Milestones:

ESMAScript Versions and Features  javascript versions


2. Early Versions: Laying the Foundation

Key Features:

  • var for variable declaration
  • Primitive types (string, number, boolean, null, undefined)
  • Functions and objects

ES1 (1997)

The first standardized version, ECMAScript 1, established core syntax, types, and basic functionalities such as loops and conditionals.

Key Features:

  • var for variable declaration
  • Primitive types (string, number, boolean, null, undefined)
  • Functions and objects

ES3 (1999)

A significant step forward, introducing features still in use today.

Key Features:

  • try...catch for error handling
  • Regular expressions
  • switch statements

ES4 (Abandoned)

This version was abandoned due to complexity and controversy over its many new features.


3. ES5 (2009): Modernizing JavaScript

ES5 marked JavaScript's shift into the modern age.

Key Features:

  • Strict Mode: Enforces safer coding practices (e.g., preventing undeclared variables).
  • JSON Support: JSON.parse() and JSON.stringify().
  • Array Methods: forEach(), map(), filter(), reduce().
  • Getters/Setters: Object property accessors.
// ES5 Array Method Example
var numbers = [1, 2, 3];
numbers.forEach(function(num) {
    console.log(num * 2);
});
// Output: 2, 4, 6

4. ES6/ES2015: The Revolution

Released in 2015, ES6 was a game changer. It improved syntax and introduced powerful new abstractions.

Key Features:

  • let and const: Block-scoped variables.
  • Arrow Functions: Concise syntax, lexical this.
  • Classes: Syntactic sugar over prototypes.
  • Promises: Improved asynchronous handling.
  • Modules: import /export syntax.
  • Template Literals: Interpolated strings with ${}.
  • Destructuring: Extracts values from arrays/objects.
// ES6 Arrow Function and Destructuring
const user = { name: 'Alice', age: 30 };
const greet = ({ name }) => `Hello, ${name}!`;
console.log(greet(user)); // "Hello, Alice!"

5. Annual Releases: ES2016 to ES2023

ES2016

  • Array.prototype.includes(): Check if an array contains a value.
  • Exponentiation operator (**): 2 ** 3 = 8.

ES2017

  • Async/Await: Makes asynchronous code look synchronous.
  • Object.values() / Object.entries(): Extract data from objects.
// Async/Await Example
async function fetchData() {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    return data;
}

ES2018

  • Spread/Rest for Objects: const clone = {...obj };
  • Promise.finally(): Executes code after promise resolution.

ES2020

  • Optional Chaining: user?.address?.city (runs only if address is not null or undefined).
  • Nullish Coalescing: const value = input ?? 'default'; (checks for null /undefined).

ES2021

  • String.replaceAll(): Replaces all instances of a substring.
  • Logical Assignment Operators: ||=, &&=, ??=.

ES2022

  • Top-Level Await: Use await outside of async functions in modules.
  • Class Fields: Declare properties directly in classes.

ES2023

  • Array.findLast(): Find from last in array.
  • Hashbang Support: Standardized syntax for CLI scripts (#!/usr/bin/env node).

6. The Rise of ES Modules and Tooling

ES6 introduced native modules, replacing older patterns like CommonJS.

// Import/Export Syntax
import { Component } from 'react';
export default function App() {};

Modern Tooling:

  • Babel: Transpile modern JS to older versions for browser compatibility.
  • Webpack/Rollup: Bundle modules for production.
  • TypeScript: Provides static typing for JavaScript.

7. Using Modern JavaScript Today

Most browsers support ES6+ features, but in older environments:

  • Transpilation: Convert modern syntax into older (e.g., Babel).
  • Polyfills: Fill missing methods (e.g., Promise).

8. The Future: ES2024 and Beyond

Proposed Features for ES2024:

  • Records and Tuples: Immutable data structures.
  • Pipeline Operator: value |> function for functional chaining.
  • Decorators: Standardizes meta-programming for classes/methods.

Conclusion: Why JavaScript’s Evolution Matters

The evolution of JavaScript parallels the increasing complexity of the web. Each version, from ES5’s strict mode to the ergonomic improvements of ES2023, enables developers to write cleaner, safer, and more efficient code.

    Select Menu