DEV Community

Nagendra Namburi
Nagendra Namburi

Posted on

🚫 Stop Writing Old JavaScript — ✅ Start Using Modern Built-in APIs (Part 2)

Missed Part 1? [Read it here] — covers structuredClone, Object.groupBy, AbortController, Promise.any, and more.


🧩 More Modern APIs You Should Already Be Using


1. Object.hasOwn()

❌ Old way

if (obj.hasOwnProperty("key")) { ... }
Enter fullscreen mode Exit fullscreen mode

⚠️ Why this is dangerous

  • hasOwnProperty can be overridden on the object itself
  • Breaks completely on null-prototype objects (e.g. Object.create(null))
const obj = Object.create(null);
obj.name = "Nagendra";

obj.hasOwnProperty("name"); // ❌ TypeError: obj.hasOwnProperty is not a function

// Also risky:
const user = {
  hasOwnProperty: () => true, // someone overrides it
};
user.hasOwnProperty("anything"); // true ❌ — lies to you
Enter fullscreen mode Exit fullscreen mode

✅ Modern way

Object.hasOwn(obj, "key");
Enter fullscreen mode Exit fullscreen mode

🧠 Real-world use cases

// Safe check on any object
const config = Object.create(null); // null-prototype object
config.theme = "dark";

Object.hasOwn(config, "theme");   // true ✅
Object.hasOwn(config, "version"); // false ✅

// Filtering only own properties (not inherited)
const base = { type: "admin" };
const user = Object.create(base);
user.name = "Nagendra";
user.age  = 28;

Object.keys(user).filter(key => Object.hasOwn(user, key));
// ["name", "age"] — excludes inherited "type" ✅

// Safe API response validation
function hasField(response, field) {
  return Object.hasOwn(response, field);
}

if (hasField(apiResponse, "data")) {
  render(apiResponse.data);
}
Enter fullscreen mode Exit fullscreen mode

2. Immutable Sorting — .toSorted()

❌ Old way

const sorted = [...arr].sort(); // spread just to avoid mutation
arr.sort();                      // mutates original ❌
Enter fullscreen mode Exit fullscreen mode

✅ Modern way

const sorted = arr.toSorted();
// original arr is untouched ✅
Enter fullscreen mode Exit fullscreen mode

🧠 Real-world use cases

const players = [
  { name: "Arjun", score: 450 },
  { name: "Priya", score: 820 },
  { name: "Rahul", score: 610 },
];

// Sort without touching the original
const leaderboard = players.toSorted((a, b) => b.score - a.score);

console.log(leaderboard[0].name); // "Priya" ✅
console.log(players[0].name);     // "Arjun" — original unchanged ✅
Enter fullscreen mode Exit fullscreen mode
// Great in React — no accidental state mutation
const [items, setItems] = useState(initialItems);

const handleSort = () => {
  // safe — doesn't mutate state directly
  const sorted = items.toSorted((a, b) => a.name.localeCompare(b.name));
  setItems(sorted);
};
Enter fullscreen mode Exit fullscreen mode
// Also available: .toReversed()
const original = [1, 2, 3, 4, 5];
const reversed = original.toReversed();

console.log(reversed);  // [5, 4, 3, 2, 1]
console.log(original);  // [1, 2, 3, 4, 5] — untouched ✅
Enter fullscreen mode Exit fullscreen mode

3. Update Array Without Mutation — .with()

❌ Old way

// Spread + map just to update one index
const updated = arr.map((item, i) => i === 2 ? "new value" : item);

// Or splice — mutates ❌
const copy = [...arr];
copy.splice(2, 1, "new value");
Enter fullscreen mode Exit fullscreen mode

✅ Modern way

const updated = arr.with(2, "new value");
// original arr untouched ✅
Enter fullscreen mode Exit fullscreen mode

🧠 Real-world use cases

const seats = ["A1", "A2", "A3", "A4", "A5"];

// Book seat at index 2
const booked = seats.with(2, "BOOKED");

console.log(booked); // ["A1", "A2", "BOOKED", "A4", "A5"]
console.log(seats);  // ["A1", "A2", "A3", "A4", "A5"] — original safe ✅
Enter fullscreen mode Exit fullscreen mode
// React state update — clean and immutable
const [cart, setCart] = useState(initialCart);

const updateQuantity = (index, qty) => {
  setCart(prev => prev.with(index, { ...prev[index], quantity: qty }));
};
Enter fullscreen mode Exit fullscreen mode
// Negative index works too
const arr = [10, 20, 30, 40, 50];
arr.with(-1, 99); // [10, 20, 30, 40, 99] — updates last item
arr.with(-2, 88); // [10, 20, 30, 88, 50] — updates second to last
Enter fullscreen mode Exit fullscreen mode

4. Find Last Matching Item — .findLast()

❌ Old way

// Reverse + find — mutates or wastes memory
const last = [...arr].reverse().find(x => x.status === "error");

// Or filter + at(-1)
const last = arr.filter(x => x.status === "error").at(-1);
// creates a whole new filtered array just for one item ❌
Enter fullscreen mode Exit fullscreen mode

✅ Modern way

const last = arr.findLast(x => x.status === "error");
Enter fullscreen mode Exit fullscreen mode

🧠 Real-world use cases

const logs = [
  { id: 1, status: "success", msg: "User logged in" },
  { id: 2, status: "error",   msg: "DB timeout" },
  { id: 3, status: "success", msg: "Data fetched" },
  { id: 4, status: "error",   msg: "API failed" },
  { id: 5, status: "success", msg: "Response sent" },
];

// Get the most recent error
const lastError = logs.findLast(log => log.status === "error");
console.log(lastError.msg); // "API failed" ✅

// Get index of most recent error
const lastErrorIndex = logs.findLastIndex(log => log.status === "error");
console.log(lastErrorIndex); // 3 ✅
Enter fullscreen mode Exit fullscreen mode
// Chat app — find last unread message
const lastUnread = messages.findLast(m => !m.read);

// Version history — find last auto-save
const lastAutoSave = history.findLast(h => h.type === "autosave");

// Transaction log — find last failed payment
const lastFailed = transactions.findLast(t => t.status === "failed");
Enter fullscreen mode Exit fullscreen mode

5. URLSearchParams

❌ Old way — manual string parsing

// Fragile, breaks with encoding, edge cases everywhere
const query = window.location.search.slice(1); // remove "?"
const params = {};
query.split("&").forEach(pair => {
  const [key, val] = pair.split("=");
  params[decodeURIComponent(key)] = decodeURIComponent(val);
});
Enter fullscreen mode Exit fullscreen mode

✅ Modern way

const params = new URLSearchParams(window.location.search);
params.get("page"); // "2"
Enter fullscreen mode Exit fullscreen mode

🧠 Real-world use cases

// URL: /products?category=shoes&sort=price&page=2

const params = new URLSearchParams(window.location.search);

params.get("category");     // "shoes"
params.get("sort");         // "price"
params.get("page");         // "2"
params.get("missing");      // null — no crash ✅
params.has("sort");         // true
Enter fullscreen mode Exit fullscreen mode
// Build query strings for API calls
const filters = new URLSearchParams({
  category: "electronics",
  minPrice: 500,
  maxPrice: 50000,
  inStock: true,
});

fetch(`/api/products?${filters.toString()}`);
// /api/products?category=electronics&minPrice=500&maxPrice=50000&inStock=true
Enter fullscreen mode Exit fullscreen mode
// Update URL without page reload (React / SPA)
const params = new URLSearchParams(window.location.search);
params.set("page", 3);
params.delete("sort");

window.history.pushState({}, "", `?${params.toString()}`);
Enter fullscreen mode Exit fullscreen mode
// Handle multi-value params
// URL: /filter?tag=js&tag=react&tag=css

const params = new URLSearchParams(window.location.search);
params.getAll("tag"); // ["js", "react", "css"] ✅
Enter fullscreen mode Exit fullscreen mode

6. Generate IDs — crypto.randomUUID()

❌ Old way — installing a package

// npm install uuid  ← unnecessary dependency
import { v4 as uuidv4 } from "uuid";
const id = uuidv4(); // "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
Enter fullscreen mode Exit fullscreen mode

✅ Modern way — built-in, zero install

const id = crypto.randomUUID();
// "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d" ✅
Enter fullscreen mode Exit fullscreen mode

🧠 Real-world use cases

// Generate unique IDs for new items
const newTodo = {
  id:        crypto.randomUUID(),
  text:      "Learn modern JS",
  completed: false,
  createdAt: new Date(),
};
Enter fullscreen mode Exit fullscreen mode
// React — stable keys for dynamic lists
const addItem = (text) => {
  setItems(prev => [
    ...prev,
    { id: crypto.randomUUID(), text, done: false }
  ]);
};

return items.map(item => (
  <TodoItem key={item.id} item={item} /> //  stable unique key
));
Enter fullscreen mode Exit fullscreen mode
// Session / request tracking
const requestId = crypto.randomUUID();

fetch("/api/data", {
  headers: { "X-Request-ID": requestId }
});

// File upload naming
const ext      = file.name.split(".").at(-1);
const filename = `${crypto.randomUUID()}.${ext}`;
// "3f2504e0-4f89-11d3-9a0c-0305e82c3301.png"
Enter fullscreen mode Exit fullscreen mode

✅ Available in all modern browsers and Node.js 14.17+
✅ Cryptographically secure — not Math.random()
❌ Uninstall the uuid package — you don't need it anymore


🔁 Quick Reference Table

Old Pattern Modern Replacement Why Better
obj.hasOwnProperty("key") Object.hasOwn(obj, "key") Safe on null-prototype objects, can't be overridden
[...arr].sort() arr.toSorted() No spread needed, original untouched
arr.reverse() arr.toReversed() Non-mutating version
arr.map() / splice to update index arr.with(index, value) One-liner, immutable
[...arr].reverse().find() arr.findLast() No copy, reads from end directly
Manual split("&") query parsing URLSearchParams Handles encoding, multi-values, edge cases
npm install uuid crypto.randomUUID() Built-in, cryptographically secure, zero deps

📚 Want to Go Deeper?

If you want to master modern JavaScript and web development from scratch to production, check out:

👉 Modern Web Course — jsden.com/courses/modern-web

You'll go beyond tips and actually build things the right way with modern APIs, patterns, and real-world projects.


🎯 Final Thoughts

Modern JavaScript keeps getting better — and most of it ships in the browser with zero install.

👉 Delete unnecessary npm packages
👉 Use Object.hasOwn() over hasOwnProperty
👉 Embrace immutable array methods — your React app will thank you
👉 crypto.randomUUID() and URLSearchParams are already on your machine


Missed Part 1? [Read it here] — covers structuredClone, Object.groupBy, AbortController, CSS :has(), Promise.any, and Intl.


Which of these were you still doing the old way? Drop it in the comments 👇

Top comments (0)