{"id":21885620,"url":"https://github.com/sheraff/til","last_synced_at":"2026-04-18T14:03:58.700Z","repository":{"id":81102181,"uuid":"199662451","full_name":"Sheraff/TIL","owner":"Sheraff","description":null,"archived":false,"fork":false,"pushed_at":"2022-07-04T22:18:02.000Z","size":7925,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-20T03:28:37.076Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://til.florianpellet.com","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sheraff.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-30T13:58:41.000Z","updated_at":"2022-07-04T22:18:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"8a70a8d0-6cec-45e2-b6fe-ed316d523bd4","html_url":"https://github.com/Sheraff/TIL","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Sheraff/TIL","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sheraff%2FTIL","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sheraff%2FTIL/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sheraff%2FTIL/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sheraff%2FTIL/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sheraff","download_url":"https://codeload.github.com/Sheraff/TIL/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sheraff%2FTIL/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31971493,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-28T10:28:18.349Z","updated_at":"2026-04-18T14:03:55.150Z","avatar_url":"https://github.com/Sheraff.png","language":"CSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"## topics\n- [ ] chrome dev tools\n  - [ ] Live Expression in Console tab allows you to write some JS and see its output live as you use the page\n- [ ] SVG anim\n- [ ] react\n  - [ ] ref as store across renders\n  - [ ] lifecycle functions have a callback as second argument\n- [ ] Web APIs \n  - [ ] IntersectionObserver\n  - [ ] IndexDB\n  - [ ] Service Worker\n- [X] CSS attribute `contain: strict;` restricts layout / paint calculations (https://developers.google.com/web/updates/2016/06/css-containment)\n- [ ] PNGs to GIF client-side using WebAssembly ImageMagick rewrite (https://github.com/KnicKnic/WASM-ImageMagick)\n- [ ] preload\n- [ ] css grid \n  - [ ] fluid width\n  - [ ] square cells hack\n- [ ] V8 TurboFan bailout reasons: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers\n- [ ] layout thrashing: https://gist.github.com/paulirish/5d52fb081b3570c81e3a\n- [ ] Object.defineProperty\n- [ ] Page lifecycle API: https://developers.google.com/web/updates/2018/07/page-lifecycle-api\n- [ ] navigator.connection.saveData \u0026\u0026 navigator.connection.effectiveType\n- [ ] networkIdleCallback ~= boredom-loading (in contrast w/ lazy-loading) (https://github.com/pastelsky/network-idle-callback): basically places a ServiceWorker to intercept all `.fetch()` and add a debounce cooldown period to trigger idleCallback (another way of doing this involves also debouncing on other user events like mouse movements, scrolling... to prevent loading smth when the user might trigger the loading of smth else)\n- [ ] Block Formatting Contexts (https://www.smashingmagazine.com//2017/12/understanding-css-layout-block-formatting-context/)\n- [ ] Static vs Live NodeList (https://www.stefanjudis.com/blog/accessing-the-dom-is-not-equal-accessing-the-dom/)\n- [ ] CSS `overscroll-behavior: contain;` to prevent a scrollable element to scroll the parent when reaching a boundary\n- [ ] CSS `backdrop-filter: blur(10px);` (https://codepen.io/chriscoyier/pen/GRKqQBo)\n- [ ] Memoization (https://nick.scialli.me/an-introduction-to-memoization-in-javascript/) (=== lazy getter?)\n- [X] Proxies https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy (cool and pertinent use cases: http://dealwithjs.io/es6-features-10-use-cases-for-proxy/) (to find use cases, google Facade pattern)\n    ```javascript\n    // objects w/ default property values\n    var handler = {\n        get: function(obj, prop) {\n            return prop in obj ?\n                obj[prop] :\n                37;\n        }\n    };\n\n    var p = new Proxy({}, handler);\n    p.a = 1;\n    p.b = undefined;\n    ```\n    Proxies can also be useful for adding properties to Arrays in a clean way\n- [X] Reflect (http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect) allows access to Object definition methods (`Reflect.set(object, property, value)`). Especially useful from within Proxies or Object.defineProperty()\n    \u003e We can use the Reflect module to call the original function that would have ran if we haven't proxied the object. We could use `obj[prop]` too, like in the previous example, but this is cleaner, and it uses the same implementation a non-proxied object would use. This maybe doesn't sound important in a simple trap like `get`, when we can easily replicate the original behavior, but some other traps like `ownKeys` would be more difficult and error prone to replicate, so it's best to get into the habit of using Reflect in my opinion.\n    —— http://dealwithjs.io/es6-features-10-use-cases-for-proxy/\n\n- [ ] Event driven architecture *needs a bit more googling* (https://github.com/gergob/jsProxy/blob/master/04-onchange-object.js)\n- [ ] `Symbol.toPrimitive` allows you do dictate how an object coerces based on the type of value the script is asking of it (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive) (https://www.keithcirkel.co.uk/metaprogramming-in-es6-symbols/)\n    ```javascript\n    // An object with Symbol.toPrimitive property.\n    const object = {\n        [Symbol.toPrimitive](hint) {\n            if (hint === 'number')\n                return 10\n            if (hint === 'string')\n                return 'hello'\n            return true\n        }\n    }\n    console.log(+object)     // 10        -- hint is \"number\"\n    console.log(`${object}`) // \"hello\"   -- hint is \"string\"\n    console.log(object + '') // \"true\"    -- hint is \"default\"\n    ```\n    `Symbol.iterator` also exists to define iterating behavior, `Symbol.species` to define the prototype\n\n- [ ] Private fields using `Symbol` or `WeakMap`\n    ```javascript\n    // in module.js\n    const privateKey = Symbol('privateField')\n    export class SymbolPrivate {\n        constructor() {\n            this[privateKey] = 42\n            console.log(`internally: ${this[privateKey]}`)\n        }\n    }\n\n    // in main.js\n    const a = new SymbolPrivate() // internally: 42\n    console.log(`externally: ${a.privateKey}`) // externally: undefined\n    console.log(a) // SymbolPrivate {Symbol(privateField): 42}\n    ```\n    w/ `Symbol`, field is readable (easy debug) but not hidden (and not secure, through `getOwnPropertySymbols`)\n    ```javascript\n    // in module.js\n    const privateInstances = new WeakMap()\n    export class WeakMapPrivate {\n        constructor() {\n            privateInstances.set(this, { privateKey: 42 })\n            console.log(`internally: ${privateInstances.get(this).privateKey}`)\n        }\n    }\n\n    // in main.js\n    const a = new WeakMapPrivate() // internally: 42\n    console.log(`externally: ${a.privateKey}`) // externally: undefined\n    console.log(a) // WeakMapPrivate {}\n    ```\n    w/ `WeakMap`, field is \"class private\" (only accessible by \"siblings\" of the same class)\n\n- [ ] Parent classes access child classes through `new.target`\n    ```javascript\n    class Unextendable {\n        constructor() {\n            if(new.target !== Unextendable)\n                throw new Error()\n        }\n    }\n    ```\n    ```javascript\n    class A {\n        constructor() {\n            new.target.classMethod()\n        }\n        static classMethod() {\n            console.log('hello from A')\n        }\n    }\n    class B extends A {\n        static classMethod() {\n            console.log('hello from B')\n        }\n    }\n    const a = new A() // hello from A\n    const b = new B() // hello from B\n    ```\n    Could be used to allow overriding how the `constructor` builds some initial state\n    ```javascript\n    class A {\n        constructor() {\n            this.state = new.target.makeState()\n        }\n        static makeState() {\n            return { }\n        }\n    }\n    class B extends A {\n        static makeState() {\n            return [ ]\n        }\n    }\n    ```\n- [ ] Uses for `void` in modern JS. It allows us to evaluate an expression and still return undefined. \"In defense of void\"\n    We're sometimes a bit quick in how we use arrow functions\n    ```javascript\n    const fn = () =\u003e doSomething(arg) // result of doSomething will leak\n    const fn = () =\u003e { doSomething(arg) } // result won't leak but intent isn't clear\n    const fn = () =\u003e void doSomething(arg) // intent is clear: call function for side-effects, drop returned value\n    ```\n    `void` is also good with IIFEs\n    Here's an example of how the classic IIFE syntax can cause issues that the void operator prevents.\n    ```javascript\n    function a() { console.log('yo') }\n    const b = a\n    void function (){ console.log('IIFE') }()\n    // instead of\n    function a() { console.log('yo') }\n    const b = a\n    (function (){ console.log('IIFE') })()\n    ```\n    Iterate over a constant array used only once, a pretty common case\n    ```javascript\n    const s = \"hello\"\n    [1, 2, 3].forEach(console.log)\n    // would be fixed by\n    void [1, 2, 3].forEach(console.log)\n    ```\n    ```javascript\n    const a = '1' + '1'\n    +a === 11 ? console.log('yes') : console.log('no')\n    ```\n    ```javascript\n    const s = \"here is a string\"\n    /[a-z]/g.exec(s) // this practically never happens though :)\n    ```\n    An easy way to think about this is: every time you are writing an expression that would usually be held within a variable, but aren't defining a variable, you should \"assign it to `void`\"\n    ```javascript\n    (function(){})()\n    // is the equivalent of\n    function iife(){}\n    iife()\n    // so without assigning to `iife`\n    void function(){}()\n    ```\n    ```javascript\n    [1, 2, 3].forEach(console.log)\n    // is the equivalent of \n    const arr = [1, 2, 3]\n    arr.forEach(console.log)\n    // so without assigning to `arr`\n    void [1, 2, 3].forEach(console.log)\n    ```\n    ```javascript\n    const fn = () =\u003e doSomething(arg)\n    // is the equivalent of \n    const fn = () =\u003e {\n        const result = doSomething(arg)\n        return result\n    }\n    // so without assigning to `result` (and without returning)\n    const fn = () =\u003e void doSomething(arg)\n    ```\n    But be careful, `void` is only applied to the the next statement\n    ```javascript\n    b = '1' + '1'\n    void +b === 11 ? console.log('yes') : console.log('no')     // no =\u003e because it reads `undefined === 11`\n    void (+b === 11) ? console.log('yes') : console.log('no')   // no =\u003e because it reads `undefined ? ... : ...`\n    void (+b === 11 ? console.log('yes') : console.log('no'))   // yes\n    ```\n- [ ] actually useful bitwise operations for day to day programming\n    * toggle between `0` and `1`\n        ```javascript\n        // using boolean type coercion `!` and number type coercion `+`\n        a = 0\n        a = +!a // 1\n        a = +!a // 0\n        // alternates between 0 and 1\n        ```\n        ```javascript\n        // using bitwise XOR operator `^` (exclusive disjuction)\n        a = 0\n        a ^= 1 // 1\n        a ^= 1 // 0\n        // alternates between N and N+1 (where N is an even integer)\n        ```\n        ```javascript\n        // using the bitwise NOT operator `~` (turns bit 0 into 1)\n        a = 0\n        a = -~-a // 1\n        a = -~-a // -0\n        a = -~-a // 1\n        // alternates between -N and N+1 (where N is the initial value of a)\n        // equivalent to a += 1-2*a\n        ```\n    * is my `indexOf` returning `-1`? \n        ```javascript\n        // bitwise NOT of 0 is -1 (and vice versa), and 0 coerces to false\n        !~-1 === true\n        ``` \n- [ ] `Math.pow()` is old, we now have exponential operator `**`\n- [ ] labeled statements\n    you can better manage nested loops that need to `break` or `continue`\n    ```javascript\n    level1: while(true) { \n        level2: while(true) { \n            break level1\n        }\n    }\n\n    while(true) { \n        while(true) { \n            break\n        }\n        break\n    }\n    ```\n    you can even `break` out of blocks that aren't loops or conditionals\n    ```javascript\n    named: {\n        console.log('yo')\n        break named\n        console.log('hey')\n    }\n    ```\n    **Use case** When speed is crucial (for example, when responding to fetch events within a Service Worker)\n    ```javascript\n    let response\n    switchBlock: {\n        const file = matchDataFileURL(event.request.url) // non trivial operation\n        if(file) {\n            response = fetchDataFile(CACHE_NAME, file)\n            break switchBlock\n        }\n        const staticImg = matchStaticImageURL(event.request.url) // non trivial operation\n        if(staticImg) {\n            response = fetchStaticImage(CACHE_NAME, staticImg)\n            break switchBlock\n        }\n        response = fetch(event.request)\n    }\n    // do something with response\n    return response\n    ```\n    to write the same script without labeled block, you'd need a series of nested `if / else` blocks\n    ```javascript\n    let response\n    const file = matchDataFileURL(event.request.url) // non trivial operation\n    if(file) {\n        response = fetchDataFile(CACHE_NAME, file)\n    } else {\n        const staticImg = matchStaticImageURL(event.request.url) // non trivial operation\n        if(staticImg) {\n            response = fetchStaticImage(CACHE_NAME, staticImg)\n        } else {\n            response = fetch(event.request)\n        }\n    }\n    // do something with response\n    return response\n    ```\n- [ ] css `mask-image` for opacity gradient (usually needs `-webkit-` prefix)\n    - example 1: fade to background (overflowing text!)\n        ```css\n        p {\n            mask-image: linear-gradient(to bottom, transparent 25%, black 75%);\n        }\n        ```\n    - example 2: clipped content ([codepen](https://codepen.io/sheraff/pen/poJNXXq))\n    ![Mask-image example: mountain photo with stripped clipping](/public/images/mask-image-example.png)\n        ```css\n        img {\n            mask-image: repeating-linear-gradient(-45deg,\n                transparent 0 20px,\n                black 20px 40px);\n        }\n        ```\n- [ ] Template literals have a grammar to call a function for custom template processing\n    ```javascript\n    console.log`a ${1} b ${2}` // [ 'a ', ' b ', '' ] 1 2\n    ```\n    ```javascript\n    function fn(parts, ...joints) {\n        console.log(parts)\n        console.log(joints)\n    }\n    fn`a ${1} b ${2}`\n    // [ 'a ', ' b ', '' ]\n    // [ 1, 2 ]\n    ```\n- [ ] css `all: initial` resets all styles \n    ```css\n    button {\n        all: initial; /* won't have any style, including vendor defaults */\n    }\n    ```\n- [ ] css `display: contents` to prevent tag from creating a box. Layout wise, all the children will behave as though they were siblings of the `display: contents` node and \"parent-to-children\" layout properties can *pass through* (like a parent `position: relative` and a child `position: absolute`, or a parent `display: flex`and a child `flex: 1`...). It still creates a node in the DOM tree (for CSS selectors and for JS `document`). See MDN [Display box model](https://developer.mozilla.org/en-US/docs/Web/CSS/display-box).\n    ```html\n    \u003cgrid\u003e\n        \u003ccard\u003e\n            \u003ccell\u003e\u003c/cell\u003e\n        \u003c/card\u003e\n    \u003c/grid\u003e\n    ```\n    ```css\n    grid { display: grid }\n    card { display: contents }\n    cell { grid-row-start: 1 }\n    ```\n- [ ] JS: sparse arrays are a thing. An array can have some of its indexes without assigned value (never assigned, deleted). \n    - It has low overhead (compared to assigning `undefined` for example), \n    - It logs out explicitely like this `[ \u003c2 empty items\u003e, 'foo', \u003c1 empty item\u003e ]`\n    - Iterators apply their callbacks *only to the values that aren't empty* \n        ```javascript\n        const array = [,1,,]\n        array.map(x =\u003e x) // [ \u003c1 empty item\u003e, 1, \u003c1 empty item\u003e ]\n        ```\n    - `.length` still counts the empty items (meaning that a `for` loop will iterate over empty items whereas a `forEach` won't)\n- [ ] css selector `:only-child`, equivalent to `:first-child:last-child`\n- [ ] JS to `querySelector` with \"preprocessor\"-like `\u0026` you can use `:scope`\n    ```js\n    const context = document.getElementById('context')\n    const selected = context.querySelectorAll(':scope \u003e div')\n    ```\n- [ ] Reconciliate *inheritance* and *composition*: create a class for common traits (entities in a game, components in a web page, ...), but instead of making a long prototype chain, compose traits from a set of possible traits.\n    ```javascript\n    class Robot {\n        constructor(id) {\n            this.id = id\n        }\n    }\n\n    const featureSet = {\n        assemble() {\n            console.log(`#${this.id} assembled an object`)\n        },\n        explore() {\n            console.log(`#${this.id} explored the planet`)\n        },\n        pickup() {\n            console.log(`#${this.id} picked up materials`)\n        },\n        sample() {\n            console.log(`#${this.id} sampled the ground`)\n        },\n    }\n\n    function composeRobot(...traits) {\n        class ComposedRobot extends Robot {}\n        traits.forEach(trait =\u003e ComposedRobot.prototype[trait] = featureSet[trait])\n        return ComposedRobot\n    }\n\n    const ScienceRobot = composeRobot('sample', 'explore')\n    const FactoryRobot = composeRobot('pickup', 'assemble')\n    const Replicator = composeRobot('explore', 'assemble')\n    const Transformer = composeRobot('assemble', 'explore', 'pickup', 'sample')\n\n    const robot1 = new ScienceRobot(3986)\n    const robot2 = new FactoryRobot(9478)\n\n    robot1.sample()   // #3986 sampled the ground\n    robot2.pickup()   // #9478 picked up materials\n    robot1.assemble() // TypeError: robot1.assemble is not a function\n    robot2.explore()  // TypeError: robot2.explore is not a function\n    ```\n- [ ] there is a base 8 integer grammar in JS (prefix number with `0`)\n    ```js\n    const a = 012 // 10 (8 + 2)\n    const b = 0120 // 80 (64 + 16)\n     ```\n\n- [ ] `AbortController` allows cancelling an ongoing XHR request\n    ```js\n    let controller\n    function request(url) {\n        if(controller)\n            controller.abort()\n        controller = new AbortController()\n        return fetch(url, {signal: controller.signal})\n        .then(() =\u003e console.log(`done: ${url}`))\n        .catch(() =\u003e console.log(`failed: ${url}`))\n    }\n    request('/endpoint?q=a')\n    request('/endpoint?q=ab')\n    request('/endpoint?q=abc')\n    // failed: /endpoint?q=a\n    // failed: /endpoint?q=ab\n    // done: /endpoint?q=abc\n    ```\n- [ ] CSS line clamping with elipsis\n    ```css\n    {\n        display: -webkit-box;\n        -webkit-line-clamp: 3;\n        -webkit-box-orient: vertical;  \n        overflow: hidden;\n    }\n    ```\n- [ ] order of script loading \u0026 execution: from [v8 dev](https://v8.dev/features/modules#defer)\n    ![](/public/images/script-async-defer.svg)\n- [ ] CSS: invert black to white, don't change colors:\n    ```css\n    filter: invert(.862745) hue-rotate(180deg);\n    ```\n- [ ] TO TEST: fix iOS 100vh issue?\n    ```css \n    .my-element {\n        height: 100vh; /* Fallback for browsers that do not support Custom Properties */\n        height: calc(var(--vh, 1vh) * 100);\n    }\n    ```\n    ```javascript\n    // First we get the viewport height and we multiple it by 1% to get a value for a vh unit\n    let vh = window.innerHeight * 0.01;\n    // Then we set the value in the --vh custom property to the root of the document\n    document.documentElement.style.setProperty('--vh', `${vh}px`);\n    ```\n- [ ] CSS `scroll-padding` (for scroll snap) also applies to anchor offsets (e.g. JS `scrollIntoView` with CSS `scroll-padding-top: 70px`)\n- [ ] JS sequence expression\n    ```javascript\n    if (val = foo(), val \u003c 10) {}\n    while (val = foo(), val \u003c 10);\n    ```\n\n- [ ] JS structure type \u0026 primitive wrapper objects\n    ```javascript\n    const a = {}\n    a.constructor === Object // true\n    typeof a === 'object'    // true\n    a instanceof Object      // true\n\n    const b = []\n    b.constructor === Array  // true\n    typeof b === 'object'    // true\n    b instanceof Array       // true\n\n    const c = 1              // primitive\n    c.constructor === Number // true\n    typeof c === 'number'    // true\n    c instanceof Number      // false\n\n    const d = new Number(1)  // primitive wrapper object\n    d.constructor === Number // true\n    typeof d === 'number'    // false\n    d instanceof Number      // true\n    d instanceof Object      // true\n\n    const e = Number('1')    // explicit primitive coercion\n    e.constructor === Number // true\n    typeof e === 'number'    // true\n    e instanceof Number      // false\n    e instanceof Object      // false\n\n    d == 1  // true\n    e == 1  // true\n    e == d  // true\n    e === 1 // true\n    d === 1 // false\n\n    class Yo{}\n    const g = new Yo()\n    g.constructor === Yo     // true\n    typeof g === 'object'    // true\n    g instanceof Yo          // true\n    g instanceof Object      // true\n    ```\n- [ ] `-webkit-tap-highlight-color` CSS property allows for setting the color of the blue highlight that flashes when tapping on mobile devices\n- [ ] `env(safe-area-inset-bottom)` CSS value is the amount of space (bottom in this case) that may be encroached on by the UI (usually 0 for standard desktops, more for iOS w/ the bottom bar, or androids w/ rounded corners)\n- [ ] JS check for specific font loaded state\n    ```javascript\n    document.fonts.check('400 1em EB Garamond')\n    ```\n- [ ] `navigator.sendBeacon` queues up a request to be sent even if the user closes the page\n- [ ] `'visibilitychange'` event on `document` is the last event reliably fired before a user leaves the page (but also fires when the user just switches to another tab/window without actually closing)\n\n- [ ] use cases for comma operator\n    ```js\n    // double for loop in one\n    const matrix = [\n        [1, 2, 3],\n        [4, 5, 6]\n    ]\n    const m = matrix.length\n    const n = matrix[0].length\n    for (\n        let i = 0, j = 0;\n        i \u003c m;\n        j++, i+=!(j%n), j%=n\n    ) {\n        console.log(matrix[i][j])\n    }\n    // 1, 2, 3, 4, 5, 6\n    ```\n    ```js\n    // avoid duplicate code to initialize a while loop\n    const set = new Set([1, 2, 3])\n    let a\n    while (a = iterator.next(), !a.done) {\n        console.log(a.value)\n    }\n    // 1, 2, 3\n    ```\n    ```js\n    // simplify small reduce functions\n    [].reduce(\n        (acc, cur) =\u003e (acc.push(cur), acc),\n        []\n    )\n    ```\n    ```js\n    // add a console log in implicit returns\n    [].reduce(\n        (acc, cur) =\u003e (console.log(cur), acc + cur),\n        0\n    )\n    ```\n\n- [ ] ways to switch\n    ```js\n    switch(a) {\n        case 1:\n            console.log(1)\n            break\n        case 2:\n            console.log(2)\n            break\n    }\n    ```\n    ```js\n    switch(true) {\n        case a === 1:\n            console.log(1)\n            break\n        case a === 2:\n            console.log(2)\n            break\n    }\n    ```\n    ```js\n    label: {\n        if (a === 1) {\n            console.log(1)\n            break label\n        }\n        if (a === 2) {\n            console.log(2)\n            break label\n        }\n    }\n    ```\n\n- [ ] useful bitwise operations II\n    ```js\n    const sign = (x) =\u003e x \u003e\u003e 31 || 1\n    // -1 | 1\n    ```\n    ```js\n    const floor = (x) =\u003e x | 0\n    // 12.6 =\u003e 12\n    ```\n    ```js\n    const odd = (x) =\u003e x \u0026 1\n    // 1 | 0\n    ```\n    ```js\n    const even = (x) =\u003e ~x \u0026 1\n    // 1 | 0\n    ```\n    ```js\n    const toggle = (x) =\u003e x ^ 1\n    // 1 | 0\n    ```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsheraff%2Ftil","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsheraff%2Ftil","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsheraff%2Ftil/lists"}