JavaScript Fundamentals — Variables, DOM, Events, and Async Programming
JavaScript is the programming language of the web — it runs in every browser and adds interactivity, dynamic content, and complex functionality to HTML and CSS.
What You’ll Learn
- Variables, data types, and modern ES6+ syntax
- Functions, objects, and arrays
- DOM manipulation and event handling
- Asynchronous programming with promises and async/await
- Fetching data from APIs
Why It Matters
JavaScript is the most widely-used programming language in the world. It powers everything from simple form validation to complex single-page applications like React and Vue. On the server side, Node.js lets you build entire applications in JavaScript. Learning JavaScript fundamentals opens doors to frontend, backend, and full-stack development.
Real-world use: The Doda Browser extension that blocks trackers and the Durga Antivirus Pro web scanner both use JavaScript to analyze page content, detect threats, and update the UI in real time without page refreshes.
Variables and Data Types
JavaScript has three ways to declare variables — let, const, and var (avoid var in modern code).
// Variable declarations (modern)
const appName = 'DodaTech Scanner'; // Can't be reassigned
let scanCount = 0; // Can be reassigned
// var is outdated — don't use it
// Data types
const string = 'Hello, world!';
const number = 42;
const float = 3.14;
const boolean = true;
const nullValue = null;
const undefinedValue = undefined;
const bigInt = 9007199254740991n;
const symbol = Symbol('unique');
// Objects and arrays
const user = {
name: 'Alice',
age: 30,
isAdmin: false
};
const colors = ['red', 'green', 'blue'];
// Template literals (ES6)
const greeting = `Hello, ${user.name}! You have ${colors.length} favorite colors.`;
console.log(greeting); // Hello, Alice! You have 3 favorite colors.
Functions
Functions are reusable blocks of code. Modern JavaScript uses arrow functions extensively.
// Function declaration
function add(a, b) {
return a + b;
}
// Arrow function (ES6)
const multiply = (a, b) => a * b;
// Arrow function with block body
const calculate = (a, b, operation) => {
switch (operation) {
case 'add': return a + b;
case 'subtract': return a - b;
case 'multiply': return a * b;
case 'divide': return a / b;
default: throw new Error('Unknown operation');
}
};
// Default parameters
const greet = (name = 'Guest') => `Welcome, ${name}!`;
// Rest parameters
const sumAll = (...numbers) => numbers.reduce((total, n) => total + n, 0);
console.log(calculate(10, 5, 'multiply')); // 50
console.log(greet()); // Welcome, Guest!
console.log(sumAll(1, 2, 3, 4)); // 10
Objects and Arrays
Objects store key-value pairs. Arrays store ordered lists. Modern JavaScript provides powerful methods for both.
// Object methods
const product = {
name: 'DodaZIP Pro',
price: 29.99,
features: ['compression', 'encryption', 'cloud-backup'],
isAvailable: true,
// Method shorthand
discount(percent) {
return this.price * (1 - percent / 100);
}
};
console.log(product.discount(20)); // 23.992
// Array methods (immutable — return new arrays)
const numbers = [1, 2, 3, 4, 5, 6];
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
const firstEven = numbers.find(n => n % 2 === 0);
const hasLarge = numbers.some(n => n > 10);
const allPositive = numbers.every(n => n > 0);
console.log(doubled); // [2, 4, 6, 8, 10, 12]
console.log(evens); // [2, 4, 6]
console.log(sum); // 21
// Destructuring
const [first, second, ...rest] = numbers;
const { name, price } = product;
console.log(first, second, rest); // 1, 2, [3, 4, 5, 6]
DOM Manipulation
The Document Object Model (DOM) is JavaScript’s interface to HTML. You can read, create, modify, and delete elements in the page.
// Selecting elements
const header = document.querySelector('header');
const buttons = document.querySelectorAll('.btn');
const main = document.getElementById('main');
const items = document.getElementsByClassName('item'); // live collection
// Creating elements
const newCard = document.createElement('div');
newCard.className = 'card';
newCard.textContent = 'New card content';
newCard.style.backgroundColor = '#f0f0f0';
// Adding to the page
document.querySelector('.container').appendChild(newCard);
// Modifying attributes
const link = document.querySelector('a');
link.setAttribute('href', 'https://example.com');
link.getAttribute('href');
link.removeAttribute('target');
// Working with classes
const element = document.querySelector('.active');
element.classList.add('highlight');
element.classList.remove('active');
element.classList.toggle('expanded');
element.classList.contains('highlight'); // true/false
// Inner HTML (careful with XSS)
const output = document.querySelector('#output');
output.innerHTML = `<p>Scan complete: <strong>${scanCount}</strong> files</p>`;Event Handling
Events let JavaScript respond to user actions — clicks, key presses, form submissions, and more.
// Click event
document.querySelector('#scan-btn').addEventListener('click', (event) => {
console.log('Scan button clicked');
console.log('Event target:', event.target);
event.preventDefault(); // Stop default behavior
});
// Form submission
document.querySelector('#search-form').addEventListener('submit', (event) => {
event.preventDefault();
const query = document.querySelector('#search-input').value;
performSearch(query);
});
// Keyboard events
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
closeModal();
}
if (event.ctrlKey && event.key === 's') {
event.preventDefault();
saveDocument();
}
});
// Input events
document.querySelector('#email').addEventListener('input', (event) => {
const isValid = event.target.validity.valid;
event.target.classList.toggle('invalid', !isValid);
});
// Event delegation — listen on parent
document.querySelector('#list').addEventListener('click', (event) => {
const item = event.target.closest('.list-item');
if (item) {
console.log('Clicked item:', item.dataset.id);
}
});Async JavaScript
JavaScript is single-threaded but handles asynchronous operations through callbacks, promises, and async/await.
Promises
// Creating a promise
const fetchData = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (url) {
resolve({ data: 'Sample response', status: 200 });
} else {
reject(new Error('URL is required'));
}
}, 1000);
});
};
// Using promises
fetchData('https://api.example.com/data')
.then(response => {
console.log(response.data);
return fetchData('https://api.example.com/more');
})
.then(moreData => console.log(moreData))
.catch(error => console.error('Error:', error.message))
.finally(() => console.log('Request complete'));Async/Await
// Modern async/await syntax
const loadDashboard = async () => {
try {
showLoadingSpinner();
const [users, scans, alerts] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/scans').then(r => r.json()),
fetch('/api/alerts').then(r => r.json())
]);
renderDashboard({ users, scans, alerts });
} catch (error) {
showError(`Failed to load dashboard: ${error.message}`);
} finally {
hideLoadingSpinner();
}
};
const showLoadingSpinner = () => { /* ... */ };
const hideLoadingSpinner = () => { /* ... */ };
const showError = (msg) => { /* ... */ };
const renderDashboard = (data) => { /* ... */ };Fetching Data from APIs
// GET request
const getUsers = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const users = await response.json();
return users;
};
// POST request
const createUser = async (userData) => {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
});
return response.json();
};
// Usage
(async () => {
const users = await getUsers();
console.log(`${users.length} users loaded`);
users.forEach(user => console.log(user.name));
})();Expected output: A list of user names from the API, ending with “10 users loaded”.
Common Errors
- TypeError: Cannot read property of null — You tried to access a property on
null. This usually means the DOM element doesn’t exist yet (script loaded before the element). - ReferenceError: x is not defined — The variable doesn’t exist. Check spelling and scope. Remember
letandconstare block-scoped. - Uncaught Promise — no catch handler — Always add
.catch()to promises or wrapawaitin try/catch. Unhandled rejections crash the process in Node.js. ==vs===confusion —==does type coercion (5 == '5'is true).===checks both value and type. Always use===.- Mutating state in React/Vue — JavaScript objects and arrays are mutable. Always create new copies when updating state to prevent bugs.
Practice Questions
What is the difference between
letandconst?letallows reassignment.constcreates a read-only reference that cannot be reassigned. However,constobjects and arrays can still have their contents modified.How does
event.preventDefault()differ fromevent.stopPropagation()?preventDefault()stops the browser’s default action (like form submission or link navigation).stopPropagation()prevents the event from bubbling up to parent elements.What is a Promise and how does async/await relate to it? A Promise represents a future value.
async/awaitis syntactic sugar over promises —awaitpauses execution until the promise settles, making asynchronous code read like synchronous code.Why is
===preferred over==?==performs type coercion, which can lead to unexpected results (e.g.,0 == falseis true).===checks both value and type, making behavior predictable and code safer.What is the DOM and how does JavaScript interact with it? The DOM (Document Object Model) is a tree representation of HTML. JavaScript uses DOM APIs (
querySelector,createElement,addEventListener, etc.) to read, create, modify, and delete page elements.
Challenge
Build a real-time search filter that fetches data from a public API (like JSONPlaceholder), displays results in a list, and filters as the user types with debouncing (300ms delay). Show a loading spinner during fetch and handle errors gracefully.
Real-World Task
Create a threat detection dashboard for Durga Antivirus Pro using JavaScript classes, DOM manipulation, and async/await. The dashboard should poll an API endpoint every 5 seconds for new threats, update a live count, display recent threats in a table, and show a notification when a critical threat is detected.
Previous: HTML Fundamentals | Previous: CSS Fundamentals | Related: Backend with Node.js
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro