Best Free Image Sites for Developers and Designers in 2025
Discover the best free stock photo and illustration websites in 2025, from AI-generated images to curated photography collections for your projects.
04/06/2026
07/05/2026
JavaScript has evolved dramatically over the past decade. What was once considered standard practice is now often outdated or harmful to your codebase. Yet many developers continue to use patterns that belong in the past.
This article explores the most persistent bad habits in JavaScript and their modern alternatives.
var: Use let and constThe var keyword uses function scoping, which leads to unexpected behavior:
if (true) {
var message = "Hello";
}
console.log(message); // "Hello" — var ignores block scope
Variables declared with var are also hoisted, which can mask bugs:
console.log(name); // undefined, not an error
var name = "Alice";
The fix: Use const by default, and let only when reassignment is needed. Both respect block scope and behave predictably.
querySelector Over Older DOM MethodsMethods like getElementById and getElementsByClassName have inconsistencies. The latter returns live HTMLCollections that don't support array methods:
const items = document.getElementsByClassName("item");
items.forEach(item => console.log(item)); // TypeError
The fix: Use querySelector and querySelectorAll. They accept any CSS selector and return consistent, iterable results:
const items = document.querySelectorAll(".item");
items.forEach(item => console.log(item)); // Works perfectly
Building strings with + is verbose and error-prone:
const greeting = "Hello, " + name + ". You are " + age + " years old.";
The fix: Template literals are cleaner and support multiline strings:
const greeting = `Hello, ${name}. You are ${age} years old.`;
Nested callbacks create unreadable code:
getUser(id, function(user) {
getOrders(user.id, function(orders) {
getDetails(orders[0].id, function(details) {
console.log(details);
});
});
});
The fix: async/await flattens the structure and centralizes error handling:
async function getOrderDetails(id) {
try {
const user = await getUser(id);
const orders = await getOrders(user.id);
const details = await getDetails(orders[0].id);
console.log(details);
} catch (error) {
console.error(error);
}
}
The == operator performs type coercion with confusing results:
console.log(0 == "0"); // true
console.log(0 == []); // true
The fix: Always use === and !== to compare both value and type.
The old pattern fails with valid falsy values:
function greet(name) {
name = name || "Guest";
}
greet(""); // Uses "Guest" instead of empty string
The fix: Use default parameters or nullish coalescing:
function greet(name = "Guest") { }
const value = input ?? "default"; // Only defaults for null/undefined
Methods like push, sort, and splice mutate the original array, causing bugs in frameworks like React.
The fix: Create new arrays instead:
const sorted = [...numbers].sort();
const withNewItem = [...numbers, 4];
const filtered = numbers.filter(n => n !== 2);
ES2023 also introduced toSorted(), toReversed(), and toSpliced() as non-mutating alternatives.
Modern JavaScript is more readable and predictable. By adopting these patterns—const/let, template literals, async/await, strict equality, and immutable operations—you'll write code that's easier to understand and maintain.
Take a look at your current projects. How many of these old habits can you spot?
Discover the best free stock photo and illustration websites in 2025, from AI-generated images to curated photography collections for your projects.
04/06/2026
Explore the most impactful CSS features released, from container queries to native nesting, and learn how they transform modern styling.
28/05/2026
Discover which web technologies have become obsolete and what modern alternatives you should adopt for your projects in 2026.
20/05/2026
Measure your knowledge, track your progress, and fill the gaps in HTML, CSS, JavaScript, PHP, SQL and more with short, focused quizzes.