String
Compare strings case-insensitively considering localization
toLowerCase
or toUpperCase
are not robust when extending beyond the Latin alphabet.const areEqual = (str1, str2, locale = "en-US") => str1.localeCompare(str2, locale, { sensitivity: "accent" }) === 0; areEqual("ß", "ss", "de"); // false areEqual("ı", "I", "tr"); // true
Funny trues
Many emojis have variations that are composed of multiple emojis, usually connected by the <ZWJ> (
U+200D
) character."😄".split(""); // ['\ud83d', '\ude04']; splits into two lone surrogates // "Backhand Index Pointing Right: Dark Skin Tone" [..."👉🏿"]; // ['👉', '🏿'] // splits into the basic "Backhand Index Pointing Right" emoji and // the "Dark skin tone" emoji // "Family: Man, Boy" [..."👨👦"]; // [ '👨', '', '👦' ] // splits into the "Man" and "Boy" emoji, joined by a ZWJ // The United Nations flag [..."🇺🇳"]; // [ '🇺', '🇳' ] // splits into two "region indicator" letters "U" and "N". // All flag emojis are formed by joining two region indicator letters
Raw
Help to escape the string original special characters
new RegExp(`^\[aaa\]$`).test("[aaa]"); // false new RegExp(String.raw`^\[aaa\]$`).test("[aaa]"); // true new RegExp(`^\\[aaa\\]$`).test("[aaa]"); // true
Regex
Difference
String.prototype.match()
and String.prototype.matchAll()
when using g
mode.match
doesn’t consider the capturing groups in regx pattern, and it only return a 1d arrayconst paragraph = 'The quick brown fox jumps over the lazy dog. It barked.'; const regex = /[A-Z]/g; const found = paragraph.match(regex); console.log(found); // Expected output: Array ["T", "I"]
matchAll
return capturing groups in regx patterns, and it is a 2d array (interable iterator object)const paragraph = 'The2 quick brown fox3 jumps over4 the5 lazy dog. It barked.'; const regex = /([a-z]+)(\d)/g; const found = paragraph.matchAll(regex); console.log([...found]); // Array [Array ["he2", "he", "2"], Array ["fox3", "fox", "3"], // Array ["over4", "over", "4"], Array ["the5", "the", "5"]]
Pitfall
String.prototype.replace()
First arguments can be
string
or regex
, and second can be function
or string
If
pattern
is a string, only the first occurrence will be replaced. To replace every occurrence, use a regular expression like /aaa/g
or use replaceAll()
Reference
Dom node compare
isEqualNode
compare deeply (Elements of the same type share defining characteristics, such as their ID, children, and attributes.)Dom manipulation
insertAdjacentElement
activeElem.insertAdjacentElement('beforebegin', tempDiv); <!-- beforebegin --> <p> <!-- afterbegin --> foo <!-- beforeend --> </p> <!-- afterend -->
after
/ before
//"<div><p></p></div>" p.before(span, "text1"); // "<div><span></span>text1<p></p></div>" //"<div><p></p></div>" p.before(span, "text1"); // "<div><p></p><span></span>text1</div>"
replaceWith
Replace the element with its parameters(place is the same as the original place)
const div = document.createElement("div"); const p = document.createElement("p"); div.appendChild(p); const span = document.createElement("span"); span.textContent = "span1"; const span2 = document.createElement("span"); span2.textContent = "span2"; const span3 = document.createElement("span"); span3.textContent = "span3"; /* <div> <span><p></p></span> </div> */ p.replaceWith(span, span2, span3); console.log(div.outerHTML); /* <div> <span>span1</span> <span>span2</span> <span>span3</span> </div> */ console.log(div.innerHTML); /* <span>span1</span> <span>span2</span> <span>span3</span> */
replaceChildren(newChild1, newChild2)
Clean existing elements and replace with new elements
// <div><p></p></div> div.replaceChildren(span, "Text"); // <div><span></span>Text</div>
replaceChild(newChild, oldChild)
//"<div><p></p></div>" div.replaceChild(p, "Text"); //"<div>Text</div>"
Create elements from template
function generateElements(html) { const template = document.createElement("template"); template.innerHTML = html.trim(); return template.content.children; } generateElements("<div>Hello World!</div>");
requestIdleCallback
Do working when idle
const task = [...] function completeTask(task){ //... } function doTaskAtIdleTime() { requestIdleCallback((deadline) => { while (deadline.timeRemaining() > 0 && tasks.length > 0) { completeTask(tasks.pop()); } if (tasks.length > 0) doTaskAtIdleTime(); }); } doTaskAtIdleTime();
Prototype chain
import "./styles.css"; class Veichle { #isRunning = false; constructor() {} start() { this.#isRunning = true; } stop() { this.#isRunning = false; } get isRunning() { return this.#isRunning; } } class Car extends Veichle { #engine; #model; constructor(engine, model) { super(); this.#engine = engine; this.#model = model; } get engine() { return this.#engine; } } const car = new Car("E1", "M1"); console.dir(car); console.dir(Car);
ƒ Car(engine, model) length: 2 name: "Car" prototype: Veichle constructor: ƒ Car(engine, model) engine: (...) isRunning: (...) get engine: ƒ () [[Prototype]]: Object constructor: ƒ Veichle() length: 0 name: "Veichle" prototype: constructor: ƒ Veichle() isRunning: (...) start: ƒ start() stop: ƒ stop() get isRunning: ƒ () [[Prototype]]: Object arguments: (...) caller: (...) [[FunctionLocation]]: index.js:5 [[Prototype]]: ƒ () [[Scopes]]: Scopes[3] isRunning: (...) start: ƒ start() stop: ƒ stop() get isRunning: ƒ () [[Prototype]]: Object arguments: (...) caller: (...) [[FunctionLocation]]: index.js:20 [[Prototype]]: ƒ Veichle() [[Scopes]]: Scopes[3]
Template tag
We define the reusable contents in
template tag
and use it by cloning it to app div.
<template id="dashboard"> <header> <h1>Bank App</h1> <a href="/login">Logout</a> </header> <section>Balance: 100$</section> <section> <h2>Transactions</h2> <table> <thead> <tr> <th>Date</th> <th>Object</th> <th>Amount</th> </tr> </thead> <tbody></tbody> </table> </section> </template> <div id="app"></div>
function updateRoute(templateId) { const template = document.getElementById(templateId); const view = template.content.cloneNode(true); const app = document.getElementById("app"); app.innerHTML = ""; app.appendChild(view); } updateRoute("dashboard");
Form
function register(e) { e.preventDefault(); // prevent submit the form and redirect const registerForm = document.getElementById("registerForm"); const formData = new FormData(registerForm); const data = Object.fromEntries(formData); const jsonData = JSON.stringify(data); } const form = document.querySelector("#form"); // Will also trigger the invalidation when click submit form.addEventListener("submit", form);
Date
Date.parse from a string
The method Date.parse(str) can read a date from a string.
The string format should be:
YYYY-MM-DDTHH:mm:ss.sssZ
, where:YYYY-MM-DD
– is the date: year-month-day.
- The character
"T"
is used as the delimiter.
HH:mm:ss.sss
– is the time: hours, minutes, seconds and milliseconds.
- The optional
'Z'
part denotes the time zone in the format+-hh:mm
. A single letterZ
would mean UTC+0.
Shorter variants are also possible, like
YYYY-MM-DD
or YYYY-MM
or even YYYY
.Performance
navigator.scheduling
navigator.scheduling.isInputPending()