[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"article-findlast-search-from-end":32,"search-suggestions":244,"related-findlast-search-from-end":281,"code:js:true:1regbnn":410,"code:js:true:59osc8":411,"code:js:true:1942iqr":412,"code:js:true:161gt37":413,"code:js:true:l6prsb":414,"code:js:true:11cppa9":415,"code:js:true:532y4v":416,"code:js:true:hh782k":417,"code:ts:true:1t5wspc":418},[4,20],{"id":5,"slug":6,"name":7,"tagline":8,"description":9,"accentFrom":10,"accentTo":11,"icon":12,"defaultLocale":13,"locales":14,"features":16,"position":19},"019fe637-3d33-714b-b57f-23e163ffca0c","dev","Web Development","Build. Learn. Ship.","Practical courses, engineering-grade articles and open-source tools for people who ship.","violet-500","cyan-400","◇","en",[13,15],"fa",{"courses":17,"paths":17,"articles":17,"exams":18,"flashcards":18,"packages":17,"community":17,"certificates":17,"teams":17,"commerce":17},true,false,0,{"id":21,"slug":22,"name":23,"tagline":24,"description":25,"accentFrom":26,"accentTo":10,"icon":27,"defaultLocale":13,"locales":28,"features":30,"position":31},"019fe637-3dc2-754c-8657-0f175bfee7c6","lang","Languages","Learn a language the way you learn a codebase.","Structured paths, listening drills and spaced repetition that actually sticks.","amber-400","⌘",[13,15,29],"es",{"courses":18,"paths":18,"articles":17,"exams":18,"flashcards":17,"packages":18,"community":17,"certificates":17,"teams":18,"commerce":18},2,{"id":33,"slug":34,"title":35,"subtitle":36,"excerpt":37,"coverUrl":38,"locale":13,"readingMinutes":39,"publishedAt":40,"viewCount":41,"likeCount":19,"commentCount":19,"author":42,"vertical":47,"topic":48,"tags":51,"_count":63,"playground":65,"body":67,"bodyMd":226,"seo":227,"translationGroupId":231,"thread":232,"assessments":234,"translations":240,"quiz":242},"019fe660-8bc3-7444-8c96-86953902f5e0","findlast-search-from-end","You copy and reverse the array to find the last match. `findLast()` searches from the end directly.",null,"The usual workaround — `[...arr].reverse().find()` — allocates a full copy just to walk it backward. ES2023 added `findLast()` and `findLastIndex()` to search from the end without touching the original.","\u002Fmedia\u002Fcovers\u002Ffindlast-search-from-end.png",3,"2026-08-14T07:38:34.486Z",52,{"id":43,"name":44,"username":45,"avatarUrl":36,"headline":46},"019fe637-3c25-7088-9034-39c9f15dc3c8","Parsa Jiravand","parsa","Frontend engineer · building bestpractic",{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":49,"name":50},"javascript","JavaScript",[52,54,57,60],{"slug":49,"name":53,"color":36},"Javascript",{"slug":55,"name":56,"color":36},"webdev","Webdev",{"slug":58,"name":59,"color":36},"frontend","Frontend",{"slug":61,"name":62,"color":36},"typescript","Typescript",{"assessments":64},1,{"slug":34,"title":66},"findLast() &amp; findLastIndex() — search from the end",{"blocks":68,"version":64},[69,73,79,82,85,90,93,97,100,104,107,111,114,118,121,125,128,131,134,137,140,143,146,150,153,157,160,164,167,170,173,178,181,184,187,190,193,196,199,202,205,208,211,214,217],{"id":70,"html":71,"type":72},"b1","\u003Cp>Here is a pattern that shows up in almost every codebase:\u003C\u002Fp>","paragraph",{"id":74,"code":75,"type":76,"language":77,"highlight":78},"b2","const lastActive = [...users].reverse().find(u => u.status === 'active');","code","js",[],{"id":80,"html":81,"type":72},"b3","\u003Cp>It works. But it creates a full copy of the array, reverses that copy in place, and then walks it from the start. All to get one element near the end. The bigger the array, the more wasteful this is — and the less obvious the intent becomes to the next reader.\u003C\u002Fp>",{"id":83,"html":84,"type":72},"b4","\u003Cp>ES2023 added \u003Ccode>findLast()\u003C\u002Fcode> to handle this directly.\u003C\u002Fp>",{"id":86,"html":87,"text":88,"type":89,"level":31},"b5","How \u003Ccode>findLast()\u003C\u002Fcode> works","How findLast() works","heading",{"id":91,"html":92,"type":72},"b6","\u003Cp>\u003Ccode>findLast()\u003C\u002Fcode> takes the same callback as \u003Ccode>find()\u003C\u002Fcode> — a predicate that receives the current element, its index, and the array — but it starts at the last index and works backward:\u003C\u002Fp>",{"id":94,"code":95,"type":76,"language":77,"highlight":96},"b7","const lastActive = users.findLast(u => u.status === 'active');",[],{"id":98,"html":99,"type":72},"b8","\u003Cp>The original array is not copied. It is not reversed. The method walks backward in a single pass and returns the first element for which the predicate returns \u003Ccode>true\u003C\u002Fcode> — which is the \u003Cem>last\u003C\u002Fem> such element from the array&#39;s perspective.\u003C\u002Fp>",{"id":101,"code":102,"type":76,"language":77,"highlight":103},"b9","const transactions = [\n  { id: 1, type: 'credit', amount: 100 },\n  { id: 2, type: 'debit',  amount: 40  },\n  { id: 3, type: 'credit', amount: 200 },\n  { id: 4, type: 'debit',  amount: 75  },\n];\n\nconst lastCredit = transactions.findLast(t => t.type === 'credit');\n\u002F\u002F { id: 3, type: 'credit', amount: 200 }",[],{"id":105,"html":106,"type":72},"b10","\u003Cp>Like \u003Ccode>find()\u003C\u002Fcode>, it returns \u003Ccode>undefined\u003C\u002Fcode> if no element matches.\u003C\u002Fp>",{"id":108,"html":109,"text":110,"type":89,"level":31},"b11","\u003Ccode>findLastIndex()\u003C\u002Fcode> for when you need the position","findLastIndex() for when you need the position",{"id":112,"html":113,"type":72},"b12","\u003Cp>\u003Ccode>findLast()\u003C\u002Fcode> returns the element. \u003Ccode>findLastIndex()\u003C\u002Fcode> returns its index — useful when you need to slice, splice, or reference the position rather than the value:\u003C\u002Fp>",{"id":115,"code":116,"type":76,"language":77,"highlight":117},"b13","const lastCreditIndex = transactions.findLastIndex(t => t.type === 'credit');\n\u002F\u002F 2\n\n\u002F\u002F Example: everything from the last credit onward\nconst tail = transactions.slice(lastCreditIndex);",[],{"id":119,"html":120,"type":72},"b14","\u003Cp>When no element matches, \u003Ccode>findLastIndex()\u003C\u002Fcode> returns \u003Ccode>-1\u003C\u002Fcode>, matching the behavior of \u003Ccode>findIndex()\u003C\u002Fcode>:\u003C\u002Fp>",{"id":122,"code":123,"type":76,"language":77,"highlight":124},"b15","transactions.findLastIndex(t => t.type === 'refund'); \u002F\u002F -1",[],{"id":126,"html":127,"type":72},"b16","\u003C!-- playground:start -->",{"id":129,"html":130,"text":130,"type":89,"level":31},"b17","🎮 Try it yourself",{"id":132,"html":133,"type":72},"b18","\u003Cp>\u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Ffindlast-search-from-end\u002Fplayground\">▶️ Open the interactive playground →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":135,"html":136,"type":72},"b19","\u003Cp>\u003Cem>Runs right in your browser — poke at it and watch the concept react live.\u003C\u002Fem>\u003C\u002Fp>",{"id":138,"html":139,"type":72},"b20","\u003C!-- playground:end -->",{"id":141,"html":142,"text":142,"type":89,"level":31},"b21","Real-world patterns",{"id":144,"html":145,"type":72},"b22","\u003Cp>\u003Cstrong>Audit logs and event histories.\u003C\u002Fstrong> You often want the most recent event matching a condition — the last failed login, the last status change, the last error before a success:\u003C\u002Fp>",{"id":147,"code":148,"type":76,"language":77,"highlight":149},"b23","const lastFailure = auditLog.findLast(e => e.level === 'error');\nif (lastFailure) {\n  showErrorBanner(lastFailure.message);\n}",[],{"id":151,"html":152,"type":72},"b24","\u003Cp>\u003Cstrong>Undo stacks.\u003C\u002Fstrong> Finding the most recent reversible operation without rebuilding the stack:\u003C\u002Fp>",{"id":154,"code":155,"type":76,"language":77,"highlight":156},"b25","const lastUndoable = history.findLast(entry => entry.undoable);",[],{"id":158,"html":159,"type":72},"b26","\u003Cp>\u003Cstrong>Form field arrays.\u003C\u002Fstrong> Finding the last populated row in a dynamic form:\u003C\u002Fp>",{"id":161,"code":162,"type":76,"language":77,"highlight":163},"b27","const lastFilledIndex = rows.findLastIndex(row => row.value.trim() !== '');\nconst rowsToSubmit = rows.slice(0, lastFilledIndex + 1);",[],{"id":165,"html":166,"type":72},"b28","\u003Cp>In all of these, the intent — &quot;the most recent X that satisfies Y&quot; — maps directly onto \u003Ccode>findLast\u003C\u002Fcode>. The \u003Ccode>[...arr].reverse().find()\u003C\u002Fcode> workaround buries that intent behind three operations.\u003C\u002Fp>",{"id":168,"html":169,"text":169,"type":89,"level":31},"b29","TypeScript types",{"id":171,"html":172,"type":72},"b30","\u003Cp>TypeScript has typed \u003Ccode>findLast()\u003C\u002Fcode> and \u003Ccode>findLastIndex()\u003C\u002Fcode> since version 4.9 — the same release that added the \u003Ccode>satisfies\u003C\u002Fcode> operator. The return type mirrors \u003Ccode>find()\u003C\u002Fcode>:\u003C\u002Fp>",{"id":174,"code":175,"type":76,"language":176,"highlight":177},"b31","interface User {\n  id: number;\n  status: 'active' | 'inactive';\n}\n\nconst users: User[] = [...];\n\nconst last = users.findLast(u => u.status === 'active');\n\u002F\u002F type: User | undefined\n\nconst lastIndex = users.findLastIndex(u => u.status === 'active');\n\u002F\u002F type: number","ts",[],{"id":179,"html":180,"type":72},"b32","\u003Cp>No extra configuration needed. The types live in \u003Ccode>lib.es2023.array.d.ts\u003C\u002Fcode> and are included automatically when your \u003Ccode>tsconfig\u003C\u002Fcode> targets ES2023 or later — or when you add \u003Ccode>&quot;ES2023&quot;\u003C\u002Fcode> to your \u003Ccode>lib\u003C\u002Fcode> array explicitly.\u003C\u002Fp>",{"id":182,"html":183,"text":183,"type":89,"level":31},"b33","Browser support",{"id":185,"html":186,"type":72},"b34","\u003Cp>\u003Ccode>findLast()\u003C\u002Fcode> and \u003Ccode>findLastIndex()\u003C\u002Fcode> are \u003Cstrong>Baseline 2022\u003C\u002Fstrong>: Chrome 97 (January 2022), Firefox 104 (August 2022), Safari 15.4 (March 2022). Node.js has supported them since version 18. There is nothing to install and no polyfill needed for any actively maintained runtime.\u003C\u002Fp>",{"id":188,"html":189,"type":72},"b35","\u003C!-- quiz:start -->",{"id":191,"html":192,"text":192,"type":89,"level":31},"b36","🧠 Test yourself",{"id":194,"html":195,"type":72},"b37","\u003Cp>Think it clicked? \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Ffindlast-search-from-end\u002Fquiz\">Take the 6-question quiz →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":197,"html":198,"type":72},"b38","\u003Cp>\u003Cem>Instant feedback, a hint on every question, and an explanation for each answer — right or wrong.\u003C\u002Fem>\u003C\u002Fp>",{"id":200,"html":201,"type":72},"b39","\u003C!-- quiz:end -->",{"id":203,"html":204,"text":204,"type":89,"level":31},"b40","The takeaway",{"id":206,"html":207,"type":72},"b41","\u003Cp>Search your codebase for \u003Ccode>reverse().find(\u003C\u002Fcode> and \u003Ccode>reverse().findIndex(\u003C\u002Fcode>. Each one is a \u003Ccode>findLast()\u003C\u002Fcode> or \u003Ccode>findLastIndex()\u003C\u002Fcode> in disguise — wrapped in a copy that exists only to flip the direction. Replace them and the intent reads directly: start from the end, return the first match you find.\u003C\u002Fp>",{"id":209,"html":210,"type":72},"b42","\u003Cp>\u003Ccode>find()\u003C\u002Fcode> and \u003Ccode>findIndex()\u003C\u002Fcode> search from the front. \u003Ccode>findLast()\u003C\u002Fcode> and \u003Ccode>findLastIndex()\u003C\u002Fcode> search from the back. They&#39;re symmetric, they&#39;re in every modern runtime, and there&#39;s no longer a reason to reach for the workaround.\u003C\u002Fp>",{"id":212,"type":213},"b43","divider",{"id":215,"html":216,"type":72},"b44","\u003Cp>\u003Cem>Thanks for reading! Let&#39;s stay connected:\u003C\u002Fem>\u003C\u002Fp>",{"id":218,"type":219,"items":220,"ordered":18},"b45","list",[221,222,223,224,225],"⭐ \u003Cstrong>GitHub\u003C\u002Fstrong> — follow me and star the projects: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fparsajiravand\">github.com\u002Fparsajiravand\u003C\u002Fa>","💬 \u003Cstrong>Discord\u003C\u002Fstrong> — join the frontend best-practices community: \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ\">discord.gg\u002Fd9KRhuAwQ\u003C\u002Fa>","📸 \u003Cstrong>Instagram\u003C\u002Fstrong> — frontend best practices, daily: \u003Ca href=\"https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F\">@bestpractice___\u003C\u002Fa>","💼 \u003Cstrong>LinkedIn\u003C\u002Fstrong> — \u003Ca href=\"https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fparsa-jiravand\u002F\">linkedin.com\u002Fin\u002Fparsa-jiravand\u003C\u002Fa>","✉️ \u003Cstrong>Email\u003C\u002Fstrong> (work &amp; contract inquiries): \u003Ca href=\"mailto:bestpractice2026@gmail.com\">bestpractice2026@gmail.com\u003C\u002Fa>","Here is a pattern that shows up in almost every codebase:\n\n```js\nconst lastActive = [...users].reverse().find(u => u.status === 'active');\n```\n\nIt works. But it creates a full copy of the array, reverses that copy in place, and then walks it from the start. All to get one element near the end. The bigger the array, the more wasteful this is — and the less obvious the intent becomes to the next reader.\n\nES2023 added `findLast()` to handle this directly.\n\n## How `findLast()` works\n\n`findLast()` takes the same callback as `find()` — a predicate that receives the current element, its index, and the array — but it starts at the last index and works backward:\n\n```js\nconst lastActive = users.findLast(u => u.status === 'active');\n```\n\nThe original array is not copied. It is not reversed. The method walks backward in a single pass and returns the first element for which the predicate returns `true` — which is the *last* such element from the array's perspective.\n\n```js\nconst transactions = [\n  { id: 1, type: 'credit', amount: 100 },\n  { id: 2, type: 'debit',  amount: 40  },\n  { id: 3, type: 'credit', amount: 200 },\n  { id: 4, type: 'debit',  amount: 75  },\n];\n\nconst lastCredit = transactions.findLast(t => t.type === 'credit');\n\u002F\u002F { id: 3, type: 'credit', amount: 200 }\n```\n\nLike `find()`, it returns `undefined` if no element matches.\n\n## `findLastIndex()` for when you need the position\n\n`findLast()` returns the element. `findLastIndex()` returns its index — useful when you need to slice, splice, or reference the position rather than the value:\n\n```js\nconst lastCreditIndex = transactions.findLastIndex(t => t.type === 'credit');\n\u002F\u002F 2\n\n\u002F\u002F Example: everything from the last credit onward\nconst tail = transactions.slice(lastCreditIndex);\n```\n\nWhen no element matches, `findLastIndex()` returns `-1`, matching the behavior of `findIndex()`:\n\n```js\ntransactions.findLastIndex(t => t.type === 'refund'); \u002F\u002F -1\n```\n\n\u003C!-- playground:start -->\n\n## 🎮 Try it yourself\n\n**[▶️ Open the interactive playground →](https:\u002F\u002Fbestpractic.org\u002Fblog\u002Ffindlast-search-from-end\u002Fplayground)**\n\n_Runs right in your browser — poke at it and watch the concept react live._\n\n\u003C!-- playground:end -->\n\n## Real-world patterns\n\n**Audit logs and event histories.** You often want the most recent event matching a condition — the last failed login, the last status change, the last error before a success:\n\n```js\nconst lastFailure = auditLog.findLast(e => e.level === 'error');\nif (lastFailure) {\n  showErrorBanner(lastFailure.message);\n}\n```\n\n**Undo stacks.** Finding the most recent reversible operation without rebuilding the stack:\n\n```js\nconst lastUndoable = history.findLast(entry => entry.undoable);\n```\n\n**Form field arrays.** Finding the last populated row in a dynamic form:\n\n```js\nconst lastFilledIndex = rows.findLastIndex(row => row.value.trim() !== '');\nconst rowsToSubmit = rows.slice(0, lastFilledIndex + 1);\n```\n\nIn all of these, the intent — \"the most recent X that satisfies Y\" — maps directly onto `findLast`. The `[...arr].reverse().find()` workaround buries that intent behind three operations.\n\n## TypeScript types\n\nTypeScript has typed `findLast()` and `findLastIndex()` since version 4.9 — the same release that added the `satisfies` operator. The return type mirrors `find()`:\n\n```ts\ninterface User {\n  id: number;\n  status: 'active' | 'inactive';\n}\n\nconst users: User[] = [...];\n\nconst last = users.findLast(u => u.status === 'active');\n\u002F\u002F type: User | undefined\n\nconst lastIndex = users.findLastIndex(u => u.status === 'active');\n\u002F\u002F type: number\n```\n\nNo extra configuration needed. The types live in `lib.es2023.array.d.ts` and are included automatically when your `tsconfig` targets ES2023 or later — or when you add `\"ES2023\"` to your `lib` array explicitly.\n\n## Browser support\n\n`findLast()` and `findLastIndex()` are **Baseline 2022**: Chrome 97 (January 2022), Firefox 104 (August 2022), Safari 15.4 (March 2022). Node.js has supported them since version 18. There is nothing to install and no polyfill needed for any actively maintained runtime.\n\n\u003C!-- quiz:start -->\n\n## 🧠 Test yourself\n\nThink it clicked? **[Take the 6-question quiz →](https:\u002F\u002Fbestpractic.org\u002Fblog\u002Ffindlast-search-from-end\u002Fquiz)**\n\n_Instant feedback, a hint on every question, and an explanation for each answer — right or wrong._\n\n\u003C!-- quiz:end -->\n\n## The takeaway\n\nSearch your codebase for `reverse().find(` and `reverse().findIndex(`. Each one is a `findLast()` or `findLastIndex()` in disguise — wrapped in a copy that exists only to flip the direction. Replace them and the intent reads directly: start from the end, return the first match you find.\n\n`find()` and `findIndex()` search from the front. `findLast()` and `findLastIndex()` search from the back. They're symmetric, they're in every modern runtime, and there's no longer a reason to reach for the workaround.\n\n---\n\n*Thanks for reading! Let's stay connected:*\n\n- ⭐ **GitHub** — follow me and star the projects: [github.com\u002Fparsajiravand](https:\u002F\u002Fgithub.com\u002Fparsajiravand)\n- 💬 **Discord** — join the frontend best-practices community: [discord.gg\u002Fd9KRhuAwQ](https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ)\n- 📸 **Instagram** — frontend best practices, daily: [@bestpractice___](https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F)\n- 💼 **LinkedIn** — [linkedin.com\u002Fin\u002Fparsa-jiravand](https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fparsa-jiravand\u002F)\n- ✉️ **Email** (work & contract inquiries): [bestpractice2026@gmail.com](mailto:bestpractice2026@gmail.com)",{"title":228,"canonical":229,"description":230},"You copy and reverse the array to find the last match. `findLast()` se","https:\u002F\u002Fbestpractic.org\u002Fblog\u002Ffindlast-search-from-end","The usual workaround — `[...arr].reverse().find()` — allocates a full copy just to walk it backward. ES2023 added `findLast()` and `findLastIndex()` to search from the end without ","019fe660-8bc3-7444-8c96-8b9136a8a194",{"id":233,"locked":18},"019fe660-929e-768b-8cf6-edb8c052336d",[235],{"id":236,"slug":34,"title":237,"_count":238},"019fe776-8197-74b8-abb9-36c3cd1d5dd5","findLast() and findLastIndex(): searching from the end",{"questions":239},6,[241],{"locale":13,"slug":34},{"id":236,"slug":34,"title":237,"_count":243,"questionCount":239},{"questions":239},[245,247,249,251,255,257,261,264,268,272,275,278],{"slug":55,"name":56,"articles":246},53,{"slug":49,"name":53,"articles":248},48,{"slug":58,"name":59,"articles":250},47,{"slug":252,"name":253,"articles":254},"css","Css",19,{"slug":61,"name":62,"articles":256},10,{"slug":258,"name":259,"articles":260},"performance","Performance",8,{"slug":262,"name":263,"articles":239},"grammar","Grammar",{"slug":265,"name":266,"articles":267},"react","React",5,{"slug":269,"name":270,"articles":271},"node","Node",4,{"slug":273,"name":274,"articles":39},"html","Html",{"slug":276,"name":277,"articles":39},"tutorial","Tutorial",{"slug":279,"name":280,"articles":39},"ai","Ai",{"items":282,"meta":408},[283,294,312,331,351,369,389],{"id":33,"slug":34,"title":35,"subtitle":36,"excerpt":37,"coverUrl":38,"locale":13,"readingMinutes":39,"publishedAt":40,"viewCount":246,"likeCount":19,"commentCount":19,"author":284,"vertical":285,"topic":286,"tags":287,"_count":292,"playground":293,"hasQuiz":17,"hasPlayground":17},{"id":43,"name":44,"username":45,"avatarUrl":36,"headline":46},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":49,"name":50},[288,289,290,291],{"slug":49,"name":53,"color":36},{"slug":55,"name":56,"color":36},{"slug":58,"name":59,"color":36},{"slug":61,"name":62,"color":36},{"assessments":64},{"slug":34},{"id":295,"slug":296,"title":297,"subtitle":36,"excerpt":298,"coverUrl":299,"locale":13,"readingMinutes":271,"publishedAt":300,"viewCount":301,"likeCount":19,"commentCount":19,"author":302,"vertical":303,"topic":304,"tags":305,"_count":310,"playground":311,"hasQuiz":17,"hasPlayground":17},"019fe661-0450-720a-ad6e-5eb995429cd7","sendbeacon-reliable-unload-data","Your `fetch()` in `beforeunload` is being silently dropped. Use `navigator.sendBeacon()`.","Browsers cancel in-flight network requests when a page unloads. The common fix — synchronous XHR — is deprecated. `navigator.sendBeacon()` is the correct, fire-and-forget API designed exactly for this case.","\u002Fmedia\u002Fcovers\u002Fsendbeacon-reliable-unload-data.png","2026-08-13T07:40:48.196Z",160,{"id":43,"name":44,"username":45,"avatarUrl":36,"headline":46},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":49,"name":50},[306,307,308,309],{"slug":49,"name":53,"color":36},{"slug":55,"name":56,"color":36},{"slug":58,"name":59,"color":36},{"slug":258,"name":259,"color":36},{"assessments":64},{"slug":296},{"id":313,"slug":314,"title":315,"subtitle":36,"excerpt":316,"coverUrl":317,"locale":13,"readingMinutes":271,"publishedAt":318,"viewCount":319,"likeCount":19,"commentCount":19,"author":320,"vertical":321,"topic":322,"tags":324,"_count":329,"playground":330,"hasQuiz":17,"hasPlayground":17},"019ff19b-f763-70e0-abdf-eded59c8e69a","overscroll-behavior-scroll-containment","You're blocking touchmove events to contain scroll. `overscroll-behavior` does it natively.","When a scrollable container hits its edge, the page behind it starts scrolling too. Developers block this with JavaScript event handlers or body overflow tricks. overscroll-behavior is the CSS property that turns off scroll chaining in one line.","\u002Fmedia\u002Fcovers\u002Foverscroll-behavior-scroll-containment.png","2026-08-12T07:38:53.786Z",185,{"id":43,"name":44,"username":45,"avatarUrl":36,"headline":46},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":252,"name":323},"CSS",[325,326,327,328],{"slug":252,"name":253,"color":36},{"slug":55,"name":56,"color":36},{"slug":58,"name":59,"color":36},{"slug":49,"name":53,"color":36},{"assessments":64},{"slug":314},{"id":332,"slug":333,"title":334,"subtitle":36,"excerpt":335,"coverUrl":336,"locale":13,"readingMinutes":271,"publishedAt":337,"viewCount":338,"likeCount":19,"commentCount":19,"author":339,"vertical":340,"topic":341,"tags":342,"_count":349,"playground":350,"hasQuiz":17,"hasPlayground":17},"019ff19b-f68d-77ea-9a2c-70e14c5c7a05","mutation-observer-dom-change-detection","You're polling setInterval to detect DOM changes. `MutationObserver` fires when they happen.","Watching for DOM mutations with setInterval or custom event dispatch is fragile and imprecise. The MutationObserver API delivers a callback exactly when attributes, text content, or child elements change — with full control over which types of mutations you watch.","\u002Fmedia\u002Fcovers\u002Fmutation-observer-dom-change-detection.png","2026-08-11T15:48:01.781Z",426,{"id":43,"name":44,"username":45,"avatarUrl":36,"headline":46},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":49,"name":50},[343,344,345,346],{"slug":49,"name":53,"color":36},{"slug":55,"name":56,"color":36},{"slug":58,"name":59,"color":36},{"slug":347,"name":348,"color":36},"dom","Dom",{"assessments":64},{"slug":333},{"id":352,"slug":353,"title":354,"subtitle":36,"excerpt":355,"coverUrl":356,"locale":13,"readingMinutes":271,"publishedAt":357,"viewCount":358,"likeCount":19,"commentCount":19,"author":359,"vertical":360,"topic":361,"tags":362,"_count":367,"playground":368,"hasQuiz":17,"hasPlayground":17},"019ff19b-f5b3-7569-8cc8-22b1136aa9b2","compressionstream-native-gzip","You're importing pako to gzip data. `CompressionStream` does it natively.","pako is one of npm's most downloaded packages — pulled in by thousands of projects to compress data before storing or sending it. CompressionStream and DecompressionStream do the same job natively, in any modern browser and Node.js 18+, with no dependencies and native C-speed execution.","\u002Fmedia\u002Fcovers\u002Fcompressionstream-native-gzip.png","2026-08-10T07:49:27.000Z",269,{"id":43,"name":44,"username":45,"avatarUrl":36,"headline":46},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":49,"name":50},[363,364,365,366],{"slug":49,"name":53,"color":36},{"slug":55,"name":56,"color":36},{"slug":58,"name":59,"color":36},{"slug":258,"name":259,"color":36},{"assessments":64},{"slug":353},{"id":370,"slug":371,"title":372,"subtitle":36,"excerpt":373,"coverUrl":374,"locale":13,"readingMinutes":271,"publishedAt":375,"viewCount":376,"likeCount":19,"commentCount":19,"author":377,"vertical":378,"topic":379,"tags":380,"_count":387,"playground":388,"hasQuiz":17,"hasPlayground":17},"019fe660-fcbe-745e-a443-5ae33ac10aaf","broadcast-channel-cross-tab-messaging","Stop using the localStorage hack to sync browser tabs. BroadcastChannel does it natively.","Syncing state across browser tabs with localStorage events is a widely-used trick that requires JSON.stringify, event filtering, and careful cleanup. The Broadcast Channel API delivers messages between tabs directly, with none of the side effects.","\u002Fmedia\u002Fcovers\u002Fbroadcast-channel-cross-tab-messaging.png","2026-08-09T07:02:41.629Z",341,{"id":43,"name":44,"username":45,"avatarUrl":36,"headline":46},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":49,"name":50},[381,382,383,384],{"slug":49,"name":53,"color":36},{"slug":55,"name":56,"color":36},{"slug":58,"name":59,"color":36},{"slug":385,"name":386,"color":36},"apis","Apis",{"assessments":64},{"slug":371},{"id":390,"slug":391,"title":392,"subtitle":36,"excerpt":393,"coverUrl":394,"locale":13,"readingMinutes":267,"publishedAt":395,"viewCount":396,"likeCount":19,"commentCount":19,"author":397,"vertical":398,"topic":399,"tags":401,"_count":406,"playground":407,"hasQuiz":17,"hasPlayground":17},"019ff19b-f388-73f8-aa5b-93d73337d6fd","dialog-element-native-modal","You built your modal with a `\u003Cdiv>` and a focus trap library. The native `\u003Cdialog>` does all of that.","The `\u003Cdialog>` element ships with focus trapping, Escape-to-close, backdrop rendering, and correct ARIA semantics — no library, no boilerplate. It's been Baseline since 2022.","\u002Fmedia\u002Fcovers\u002Fdialog-element-native-modal.png","2026-08-08T07:00:10.810Z",212,{"id":43,"name":44,"username":45,"avatarUrl":36,"headline":46},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":273,"name":400},"HTML",[402,403,404,405],{"slug":273,"name":274,"color":36},{"slug":55,"name":56,"color":36},{"slug":58,"name":59,"color":36},{"slug":49,"name":53,"color":36},{"assessments":64},{"slug":391},{"page":64,"perPage":409,"total":248,"totalPages":409},7,"\u003Cdiv class=\"shj shj-lang-js shj-oneline\" data-lang=\"js\">\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> lastActive \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">...\u003C\u002Fspan>users\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">reverse\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">find\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>u \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> u\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>status \u003Cspan class=\"shj-oper\">===\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'active'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-oneline\" data-lang=\"js\">\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> lastActive \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> users\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">findLast\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>u \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> u\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>status \u003Cspan class=\"shj-oper\">===\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'active'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003Cdiv>9\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> transactions \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\n  \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> id\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-num\">1\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> type\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'credit'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> amount\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-num\">100\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> id\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-num\">2\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> type\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'debit'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>  amount\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-num\">40\u003C\u002Fspan>  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> id\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-num\">3\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> type\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'credit'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> amount\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-num\">200\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> id\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-num\">4\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> type\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'debit'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>  amount\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-num\">75\u003C\u002Fspan>  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>;\n\n\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> lastCredit \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> transactions\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">findLast\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>t \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> t\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>type \u003Cspan class=\"shj-oper\">===\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'credit'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\u003Cspan class=\"shj-cmnt\">\u002F\u002F { id: 3, type: 'credit', amount: 200 }\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> lastCreditIndex \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> transactions\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">findLastIndex\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>t \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> t\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>type \u003Cspan class=\"shj-oper\">===\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'credit'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\u003Cspan class=\"shj-cmnt\">\u002F\u002F 2\n\u003C\u002Fspan>\n\u003Cspan class=\"shj-cmnt\">\u002F\u002F Example: everything from the last credit onward\n\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> tail \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> transactions\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">slice\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>lastCreditIndex\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-oneline\" data-lang=\"js\">transactions\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">findLastIndex\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>t \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> t\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>type \u003Cspan class=\"shj-oper\">===\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'refund'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>; \u003Cspan class=\"shj-cmnt\">\u002F\u002F -1\u003C\u002Fspan>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> lastFailure \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> auditLog\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">findLast\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>e \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> e\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>level \u003Cspan class=\"shj-oper\">===\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'error'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\u003Cspan class=\"shj-kwd\">if\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>lastFailure\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-func\">showErrorBanner\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>lastFailure\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>message\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-oneline\" data-lang=\"js\">\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> lastUndoable \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> history\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">findLast\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>entry \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> entry\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>undoable\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> lastFilledIndex \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> rows\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">findLastIndex\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>row \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> row\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>value\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">trim\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-oper\">!==\u003C\u002Fspan> \u003Cspan class=\"shj-str\">''\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> rowsToSubmit \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> rows\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">slice\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-num\">0\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> lastFilledIndex \u003Cspan class=\"shj-oper\">+\u003C\u002Fspan> \u003Cspan class=\"shj-num\">1\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003Cdiv>9\u003C\u002Fdiv>\u003Cdiv>10\u003C\u002Fdiv>\u003Cdiv>11\u003C\u002Fdiv>\u003Cdiv>12\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">interface\u003C\u002Fspan> \u003Cspan class=\"shj-class\">User\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  id\u003Cspan class=\"shj-type\">: number\u003C\u002Fspan>;\n  status\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'active'\u003C\u002Fspan> \u003Cspan class=\"shj-oper\">|\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'inactive'\u003C\u002Fspan>;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\n\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> users\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-class\">User\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan> \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">...\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>;\n\n\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> last \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> users\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">findLast\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>u \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> u\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>status \u003Cspan class=\"shj-oper\">===\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'active'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\u003Cspan class=\"shj-cmnt\">\u002F\u002F type: User | undefined\n\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> lastIndex \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> users\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">findLastIndex\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>u \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> u\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>status \u003Cspan class=\"shj-oper\">===\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'active'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\u003Cspan class=\"shj-cmnt\">\u002F\u002F type: number\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>"]