JavaScript Notes: Number Formatting, URI Encoding and Selectors
Use toLocaleString() to format JavaScript numbers, and encodeURIComponent() to encode an individual URI component. For query parameters, URL and URLSearchParams handle separators and encoding together. These notes explain number display, URI encoding and selector behavior as separate tasks.
Format numbers for display
(123456789).toLocaleString("en-US"); // "123,456,789"
A locale defines language and regional formatting rules. Specify one when you need predictable separators, and remember that the formatted result is a string. Keep the original number for calculations. Options for decimal places and parsing grouped input are covered in adding and removing thousands separators.
Encode a complete URI and an individual component differently
A Uniform Resource Identifier (URI) identifies a resource; a web URL is one kind of URI. URI encoding represents characters such as spaces or reserved punctuation in a form appropriate for the relevant URI component. It is not encryption and does not make arbitrary HTML safe to insert into a page.
| Task | Function | Important distinction |
|---|---|---|
| Preserve the structure of a complete URI | encodeURI() |
Keeps structural characters such as :, /, ?, & |
| Encode one query value or component | encodeURIComponent() |
Encodes delimiters inside the value, including &, = and ? |
| Decode encodeURI output | decodeURI() |
Preserves reserved delimiters as defined for whole URIs |
| Decode an encoded component | decodeURIComponent() |
Decodes an individual value |
encodeURI("https://example.com/search?q=coffee&sort=new");
// Preserves the structural characters ?, =, &
encodeURIComponent("coffee&tea"); // "coffee%26tea"
decodeURIComponent("coffee%26tea"); // "coffee&tea"
Using encodeURI() on a query value containing & can leave that character available as a parameter separator. Use encodeURIComponent() for an individual value; encodeURI() has a different purpose. Encoding an already encoded value can also turn % into %25, producing double encoding.
Build query parameters from their original values
const url = new URL("https://example.com/search");
url.searchParams.set("q", "coffee & tea");
url.searchParams.set("page", "1");
console.log(url.href);
// https://example.com/search?q=coffee+%26+tea&page=1
URLSearchParams manages parameter names and values. Pass the original text instead of calling encodeURIComponent() first: serialization performs the necessary encoding. In its form-style encoding, spaces can appear as +. Read the value back with url.searchParams.get("q"), which handles the encoded representation. The URLSearchParams reference explains these rules.
Handle decoding errors and legacy functions
function decodeComponentSafely(text) {
try {
return decodeURIComponent(text);
} catch (error) {
if (error instanceof URIError) return null;
throw error;
}
}
decodeComponentSafely("%E0%A4%A"); // null: malformed encoding
Malformed percent encoding can make decodeURIComponent() throw URIError. The helper above returns null for that failure and rethrows unrelated errors. When reading a query string, parse each parameter through the appropriate tool rather than decoding the whole string and then splitting it. See decodeURIComponent() exceptions.
The legacy escape() and unescape() functions are not recommended substitutes for URI encoding. Before migrating stored data, identify the function that produced it: older %uXXXX representations are not automatically compatible with decodeURIComponent(). The escape() reference describes its legacy status.
CSS selectors in current browsers
#items li:nth-child(2) {
color: #a00000;
}
#items li:last-child {
font-weight: bold;
}
CSS, or Cascading Style Sheets, controls page presentation. Pseudo-classes such as :nth-child() select elements based on a position or state. Put the example in a CSS file or style element to style the second list item and the final item. :nth-child() counts all element siblings, so mixed element types can change which item matches; :nth-of-type() counts siblings of a particular type. The :nth-child() reference explains the selection rules.
Older notes may mention selectivizr to supplement CSS selectors in Internet Explorer 8. Current browsers do not require that historical workaround for these selectors. If you maintain a separate IE8 environment, check its support independently; the modern JavaScript syntax in this article is not an IE8 compatibility solution.
Complete example: build a search URL and recover the value
Save the example as javascript-notes.html in UTF-8 and open it in a current browser. It displays a URL without sending a search request. It uses textContent for output and adds a class to the second list item with querySelectorAll().
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Encoding strings and query parameters</title>
<style>
body { margin: 24px; font: 16px/1.7 sans-serif; }
input, button, select { font: inherit; max-width: 100%; }
label { display: block; margin-top: 12px; }
#output { white-space: pre-wrap; overflow-wrap: anywhere; }
</style>
</head>
<body>
<label for="query">Search term</label>
<input id="query" type="text" value="coffee & tea">
<button id="encode" type="button">Build URL</button>
<ul id="items"><li>First</li><li>Second</li><li>Third</li></ul>
<pre id="output" aria-live="polite"></pre>
<script>
function show() {
const value = document.getElementById("query").value;
const encoded = encodeURIComponent(value);
const url = new URL("https://example.com/search");
url.searchParams.set("q", value);
const lines = [
`Component encoding: ${encoded}`,
`Decoded: ${decodeURIComponent(encoded)}`,
`Search URL: ${url.href}`,
`Formatted number: ${(123456789).toLocaleString("en-US")}`
];
document.getElementById("output").textContent = lines.join("\n");
}
const second = document.querySelectorAll("#items li:nth-child(2)");
for (const item of second) item.classList.add("selected");
document.getElementById("encode").addEventListener("click", show);
show();
</script>
</body>
</html>
For "coffee & tea", component encoding displays %20 for spaces and %26 for the ampersand. The decoded line restores the original input, while the URLSearchParams URL uses + for spaces. The second li receives the selected class. Adding a class does not itself change the color: apply the corresponding CSS if you want a visible highlight.

