Skip to main content

3 posts tagged with "JavaScript"

View All Tags

Scope, Hoisting and Reassignment in JavaScript

· 5 min read
Kamlesh
Quality Assurance @TestKarts

Table of Contents


1. Understanding Scope, Hoisting and Reassignment

Let's embark on a journey to explore the fundamental concepts of scope, hoisting, and variable reassignment in JavaScript. By understanding these concepts, we can easily grasp the differences between var, let, and const declarations, comprehend their scoping rules, examine how hoisting impacts variable declarations, and determine whether reassignment is allowed. So, let's dive right in and unravel the mysteries of these essential JavaScript concepts!

Scope

In JavaScript, there are three types of scope:

  • Global Scope
  • Function Scope
  • Block Scope
  1. Global Scope: The global scope is the outermost scope in JavaScript and is accessible throughout the entire codebase. Variables declared in the global scope are accessible from any part of the code, including inside functions and blocks.

Example:

var x = 10;

function example() {
console.log(x); // Output: 10
}

example();

In the above example, x is declared in the global scope and can be accessed both inside the function example() and outside of it.

  1. Function Scope: Variables declared inside a function have function scope. They are accessible only within the function in which they are defined, and they are not accessible from outside the function.

Example:

function example() {
var x = 10;
console.log(x); // Output: 10
}

example();
console.log(x); // Output: ReferenceError: x is not defined

In the above example, x is defined inside the example() function and is accessible only within that function. Attempting to access x outside the function will result in a ReferenceError.

  1. Block Scope: Block scope was introduced in ECMAScript 2015 (ES6) with the introduction of let and const keywords. Variables declared with let and const have block scope, which means they are only accessible within the block in which they are defined. A block is typically delimited by curly braces {}.

Example:

function example() {
if (true) {
let x = 10;
const y = 20;
console.log(x); // Output: 10
console.log(y); // Output: 20
}
console.log(x); // Output: ReferenceError: x is not defined
console.log(y); // Output: ReferenceError: y is not defined
}

example();

In the above example, x and y are declared inside the if block and are accessible only within that block. Attempting to access x or y outside the block will result in a ReferenceError.


Reassignment

Variable reassignment refers to the act of assigning a new value to an already declared variable.

Here's an example in JavaScript:

let count = 5; //Assign
console.log(count); // Output: 5

count = 10; //Reassign
console.log(count); // Output: 10

count = count + 2; //Reassign
console.log(count); // Output: 12

In this example, the variable count is initially assigned a value of 5. Then, it is reassigned to a value of 10 and later updated by adding 2 to its current value, resulting in a final value of 12.

Variable reassignment allows for dynamic and flexible programming by allowing variables to store different values at different points in the program's execution. It enables the modification and manipulation of data throughout the program to reflect changing conditions or calculations.


Hoisting

Definition
  • Hoisting is a behavior in JavaScript where variable and function declarations are moved to the top of their containing scope during the compilation phase.
  • This means that regardless of where variables and functions are declared in the code, they are conceptually moved to the top of their respective scopes.

Here's a simplified example to illustrate hoisting:

The reason why variables and functions behave differently when hoisted in JavaScript is due to how they are initialized during the hoisting process.

1. In Case of Variable

  • Variable declarations are hoisted but not their assignments.
  • When a variable declaration is hoisted, it is moved to the top of its scope, but its assignment remains in place.

This is why variables declared with var are initially assigned a default value of undefined before the actual assignment statement is reached in the code.

2. In Case of function

  • On the other hand, function declarations are hoisted along with their complete definition, including the function body.

This means that the entire function, including its code, is moved to the top of its scope during the hoisting process. As a result, functions can be called and executed before their actual declaration in the code, without any undefined value.

To illustrate with an example:

var a = 20; // Initialize a
var b; // Declare b

console.log(x); // Output: undefined
var x = 5;

foo(); // Output: "Hello!"

function foo() {
console.log("Hello!");
}

In this code, the variable x is hoisted to the top of its scope, resulting in undefined when accessed before its assignment. On the other hand, the function foo() is hoisted along with its definition, so it can be called and executed without any undefined value.

It's important to note that this behavior applies specifically to function declarations and variables declared with var.

caution

Other forms of variable declaration, such as let and const, do not exhibit hoisting in the same way and will result in a ReferenceError if accessed before their declaration.

To avoid confusion caused by hoisting, it is generally recommended to declare variables at the beginning of their scope, rather than relying on hoisting to bring them to the top.

var vs let vs const in JavaScript

· 3 min read
Kamlesh
Quality Assurance @TestKarts

Table of Contents


Understanding the fundamental concepts of scope, hoisting, and variable reassignment in JavaScript is crucial in order to grasp the differences between var, let, and const declarations. If you're not familiar with these concepts.

Note- I recommend clicking here to learn more about scope, hoisting, and variable reassignment and gain a better understanding.

Main Differences:

  • var: It has function scope or global scope, is hoisted, allows reassignment, and is not block-scoped.
  • let: It has block scope, is not hoisted, allows reassignment, and is block-scoped.
  • const: It has block scope, is not hoisted, does not allow reassignment after initialization, and is block-scoped.

Understanding Key differences between var, let, and const Using Table

ScopeHoistingReassignmentBlock-Scoped
varFunction-scoped (or Global-scoped)HoistedAllowedNo
letBlock-scopedNot hoistedAllowedYes
constBlock-scopedNot hoistedNot allowedYes

Now let's provide examples to illustrate these differences:

  1. Scope:
    • var example:
function example() {
if (true) {
var x = 10;
}
console.log(x); // Output: 10
}
example();

The variable x declared with var inside the if block is accessible outside the block due to function scope.

  • let example:
function example() {
if (true) {
let x = 10;
}
console.log(x); // Output: ReferenceError: x is not defined
}
example();

The variable x declared with let inside the if block is not accessible outside the block due to block scope.

  • const example:
function example() {
if (true) {
const x = 10;
}
console.log(x); // Output: ReferenceError: x is not defined
}
example();

Similar to let, the variable x declared with const inside the if block is not accessible outside the block due to block scope.

  1. Hoisting:

    • var example:
    console.log(x); // Output: undefined
    var x = 10;
    console.log(x); // Output: 10

    Variables declared with var are hoisted to the top of their scope, which means they can be accessed before their declaration, but their initial value is undefined.

    • let example:
    console.log(x); // Output: ReferenceError: x is not defined
    let x = 10;
    console.log(x); // Output: 10

    Variables declared with let are not hoisted, and attempting to access them before their declaration results in a ReferenceError.

    • const example:
    console.log(x); // Output: ReferenceError: x is not defined
    const x = 10;
    console.log(x); // Output: 10

    Similar to let, variables declared with const are also not hoisted, and attempting to access them before their declaration results in a ReferenceError.

  2. Reassignment:

    • var example:
    var x = 10;
    x = 20;
    console.log(x); // Output: 20

    Variables declared with var can be reassigned to new values.

    • let example:
    let x = 10;
    x = 20;
    console.log(x); // Output: 20

    Variables declared with let can also be reassigned to new values.

    • const example:
    const x = 10;
    x = 20; // Error: Assignment to constant variable.

I encourage you to take another look at the table provided here and familiarize yourself with the key differences between var, let, and const declarations. Understanding these distinctions will help you effectively utilize and differentiate between these variable declaration keywords in JavaScript.

How to Create a Responsive Horizontal Scrolling Card Slider in JavaScript

· 7 min read
Kamlesh
Quality Assurance @TestKarts

Introduction:

Horizontal scrolling is a popular UI pattern used in many modern web applications. A horizontal card slider is a similar design pattern that allows users to scroll through a set of cards horizontally. In this tutorial, we'll be using JavaScript and CSS to create a horizontal card slider with forward and backward scrolling buttons. Horizontal Card slider with arrow

Features:

  • Step-by-step instructions: The post provides a detailed and easy-to-follow tutorial on how to create a horizontal scrolling card with forward and back buttons.

  • Interactive functionality: The post provides code that allows users to interact with the horizontal scrolling card by clicking on the forward and back buttons to slide the cards left or right.

  • End-of-scroll detection: The post includes code to detect when the horizontal scroll has reached either end, and disables the relevant button to prevent users from scrolling further.

  • Default state: The post explains how to set the default state of the horizontal scroll to be at the leftmost card and disable the back button.

  • Customizable code: The post provides code that can be customized to fit different design and functionality requirements.

Implementation:

To create a horizontal card slider, we first need to create a container element with a fixed width and overflow-x set to scroll. Inside the container, we'll add a set of card elements that are floated left and have a fixed width.

Next, we'll use JavaScript to detect when the slider reaches the left or right end and disable the corresponding arrow button. We'll also add event listeners to the arrow buttons to scroll the slider left or right when clicked.

Here's the complete code to implement a horizontal card slider with forward and backward scrolling buttons:

Here are the steps to follow:

Step 1: Create the HTML markup

Create an HTML element to hold the cards that will be horizontally scrolled. Inside this element, create a container for the cards that will be scrolled. Each card should be wrapped in a div element. Here's an example:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<script src="https://kit.fontawesome.com/a59b9b09ab.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<link rel="stylesheet" href="style.css" />
<title>Static Template</title>
</head>

<body>
<div class="cover">
<button class="left" onclick="leftScroll()">
<i class="fas fa-angle-double-left"></i>
</button>
<div class="scroll-images">
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-1-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM9.283 4.002H7.971L6.072 5.385v1.271l1.834-1.318h.065V12h1.312V4.002Z"/>
</svg>
<h4>Card 1</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-2-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM6.646 6.24c0-.691.493-1.306 1.336-1.306.756 0 1.313.492 1.313 1.236 0 .697-.469 1.23-.902 1.705l-2.971 3.293V12h5.344v-1.107H7.268v-.077l1.974-2.22.096-.107c.688-.763 1.287-1.428 1.287-2.43 0-1.266-1.031-2.215-2.613-2.215-1.758 0-2.637 1.19-2.637 2.402v.065h1.271v-.07Z"/>
</svg>
<h4>Card 2</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-3-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-8.082.414c.92 0 1.535.54 1.541 1.318.012.791-.615 1.36-1.588 1.354-.861-.006-1.482-.469-1.54-1.066H5.104c.047 1.177 1.05 2.144 2.754 2.144 1.653 0 2.954-.937 2.93-2.396-.023-1.278-1.031-1.846-1.734-1.916v-.07c.597-.1 1.505-.739 1.482-1.876-.03-1.177-1.043-2.074-2.637-2.062-1.675.006-2.59.984-2.625 2.12h1.248c.036-.556.557-1.054 1.348-1.054.785 0 1.348.486 1.348 1.195.006.715-.563 1.237-1.342 1.237h-.838v1.072h.879Z"/>
</svg>
<h4>Card 3</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-4-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM7.519 5.057c-.886 1.418-1.772 2.838-2.542 4.265v1.12H8.85V12h1.26v-1.559h1.007V9.334H10.11V4.002H8.176c-.218.352-.438.703-.657 1.055ZM6.225 9.281v.053H8.85V5.063h-.065c-.867 1.33-1.787 2.806-2.56 4.218Z"/>
</svg>
<h4>Card 4</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-5-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-8.006 4.158c1.74 0 2.924-1.119 2.924-2.806 0-1.641-1.178-2.584-2.56-2.584-.897 0-1.442.421-1.612.68h-.064l.193-2.344h3.621V4.002H5.791L5.445 8.63h1.149c.193-.358.668-.809 1.435-.809.85 0 1.582.604 1.582 1.57 0 1.085-.779 1.682-1.57 1.682-.697 0-1.389-.31-1.53-1.031H5.276c.065 1.213 1.149 2.115 2.72 2.115Z"/>
</svg>
<h4>Card 5</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-6-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM8.21 3.855c-1.868 0-3.116 1.395-3.116 4.407 0 1.183.228 2.039.597 2.642.569.926 1.477 1.254 2.409 1.254 1.629 0 2.847-1.013 2.847-2.783 0-1.676-1.254-2.555-2.508-2.555-1.125 0-1.752.61-1.98 1.155h-.082c-.012-1.946.727-3.036 1.805-3.036.802 0 1.213.457 1.312.815h1.29c-.06-.908-.962-1.899-2.573-1.899Zm-.099 4.008c-.92 0-1.564.65-1.564 1.576 0 1.032.703 1.635 1.558 1.635.868 0 1.553-.533 1.553-1.629 0-1.06-.744-1.582-1.547-1.582Z"/>
</svg>
<h4>Card 6</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-7-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM5.37 5.11h3.972v.07L6.025 12H7.42l3.258-6.85V4.002H5.369v1.107Z"/>
</svg>
<h4>Card 7</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-8-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-5.03 1.803c0-1.248-.943-1.84-1.646-1.992v-.065c.598-.187 1.336-.72 1.336-1.781 0-1.225-1.084-2.121-2.654-2.121-1.57 0-2.66.896-2.66 2.12 0 1.044.709 1.589 1.33 1.782v.065c-.697.152-1.647.732-1.647 2.003 0 1.39 1.19 2.344 2.953 2.344 1.77 0 2.989-.96 2.989-2.355Zm-4.347-3.71c0 .739.586 1.255 1.383 1.255s1.377-.516 1.377-1.254c0-.733-.58-1.23-1.377-1.23s-1.383.497-1.383 1.23Zm-.281 3.645c0 .838.72 1.412 1.664 1.412.943 0 1.658-.574 1.658-1.412 0-.843-.715-1.424-1.658-1.424-.944 0-1.664.58-1.664 1.424Z"/>
</svg>
<h4>Card 8</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-9-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-8.223 4.146c2.104 0 3.123-1.464 3.123-4.3 0-3.147-1.459-4.014-2.97-4.014-1.63 0-2.871 1.02-2.871 2.73 0 1.706 1.171 2.667 2.566 2.667 1.06 0 1.7-.557 1.934-1.184h.076c.047 1.67-.475 3.023-1.834 3.023-.71 0-1.149-.363-1.248-.72H5.258c.094.908.926 1.798 2.52 1.798Zm.118-3.972c.808 0 1.535-.528 1.535-1.594s-.668-1.676-1.56-1.676c-.838 0-1.517.616-1.517 1.659 0 1.072.708 1.61 1.54 1.61Z"/>
</svg>
<h4>Card 9</h4>
</div>
</div>
<button class="right" onclick="rightScroll()">
<i class="fas fa-angle-double-right"></i>
</button>
</div>
</body>
</html>

Step 2: Add CSS

Add CSS to create the horizontal scroll effect. Set the scroll-container element to overflow-x: scroll to allow horizontal scrolling. Set the width of each card to the desired width and make sure they are displayed inline-block. Here's an example:

.cover {
position: relative;
padding: 0px 30px;
margin-top: 100px;
}

.left {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}

.right {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
}

.scroll-images {
position: relative;
width: 100%;
padding: 40px 0px;
height: auto;
display: flex;
flex-wrap: nowrap;
overflow-x: hidden;
overflow-y: hidden;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
}

.child {
display: flex;
justify-content: center;
align-items: center;
min-width: 250px;
height: 200px;
padding: 0px 15px;
margin: 1px 10px;
border: 1px solid #f1f1f1;
overflow: hidden;
-webkit-box-shadow: 0px 0px 15px 2px rgb(0 0 0 / 10%);;
box-shadow: 0px 0px 15px 2px rgb(0 0 0 / 10%);;
}

.child img, .child > svg {
position: absolute;
margin-top: -195px;
width: 80px;
height: 80px;
object-fit: cover;
object-position: center;
border-radius: 50%;
background: #03A9F4;
}

.scroll-images::-webkit-scrollbar {
width: 5px;
height: 8px;
background-color: #aaa;
}

.scroll-images::-webkit-scrollbar-thumb {
background-color: black;
}

button {
background-color: transparent;
border: none;
outline: none;
cursor: pointer;
font-size: 25px;
}

Step 3: Add JavaScript

Add JavaScript to handle the scrolling and enable/disable the arrow buttons. Here's an example:

document.addEventListener("DOMContentLoaded", function () {
const scrollImages = document.querySelector(".scroll-images");
const scrollLength = scrollImages.scrollWidth - scrollImages.clientWidth;
const leftButton = document.querySelector(".left");
const rightButton = document.querySelector(".right");

function checkScroll() {
const currentScroll = scrollImages.scrollLeft;
if (currentScroll === 0) {
leftButton.setAttribute("disabled", "true");
rightButton.removeAttribute("disabled");
} else if (currentScroll === scrollLength) {
rightButton.setAttribute("disabled", "true");
leftButton.removeAttribute("disabled");
} else {
leftButton.removeAttribute("disabled");
rightButton.removeAttribute("disabled");
}
}

scrollImages.addEventListener("scroll", checkScroll);
window.addEventListener("resize", checkScroll);
checkScroll();

function leftScroll() {
scrollImages.scrollBy({
left: -200,
behavior: "smooth"
});
}

function rightScroll() {
scrollImages.scrollBy({
left: 200,
behavior: "smooth"
});
}

leftButton.addEventListener("click", leftScroll);
rightButton.addEventListener("click", rightScroll);
});

Customize the JavaScript to fit your specific needs. For example, you may need to change the width of each card or the amount that the scroll container scrolls when the arrow buttons are clicked.

And that's it! With these steps, you can create a card horizontal scrolling with forward and back arrow buttons that enable/disable depending on the scroll position.

Try on CodePen :-