{"id":28298156,"url":"https://github.com/squirrelsquirrel78/javascript","last_synced_at":"2026-02-02T08:03:46.141Z","repository":{"id":114470681,"uuid":"156224837","full_name":"squirrelsquirrel78/javascript","owner":"squirrelsquirrel78","description":"Notes on JavaScript + DSA","archived":false,"fork":false,"pushed_at":"2018-12-23T15:41:27.000Z","size":92,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-29T21:05:05.816Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/squirrelsquirrel78.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2018-11-05T13:47:02.000Z","updated_at":"2025-05-22T15:46:04.000Z","dependencies_parsed_at":"2023-06-08T07:15:30.178Z","dependency_job_id":null,"html_url":"https://github.com/squirrelsquirrel78/javascript","commit_stats":null,"previous_names":["squirrelsquirrel88/javascript","squirrelsquirrel78/javascript"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/squirrelsquirrel78/javascript","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squirrelsquirrel78%2Fjavascript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squirrelsquirrel78%2Fjavascript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squirrelsquirrel78%2Fjavascript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squirrelsquirrel78%2Fjavascript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/squirrelsquirrel78","download_url":"https://codeload.github.com/squirrelsquirrel78/javascript/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squirrelsquirrel78%2Fjavascript/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29007386,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-02T06:37:10.400Z","status":"ssl_error","status_checked_at":"2026-02-02T06:37:09.383Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":"2025-05-23T06:13:15.446Z","updated_at":"2026-02-02T08:03:46.096Z","avatar_url":"https://github.com/squirrelsquirrel78.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"### Table of Contents\n\n| [Promises, async/await](#promises-async-await) |\n|-----------------|\n| [Callbacks](#callbacks) |\n\n| [Advanced Functions](#advanced-functions) |\n|-----------------|\n| [Closures](#closures) |\n| [`var`](#var) |\n| [Scheduling](#scheduling) |\n| [Throttling and debouncing](#throttling-and-debouncing) |\n| [Decorators](#decorators) |\n\n| [Basic JavaScript](#basic-javascript) |\n|-----------------|\n| [Type Conversion](#type-conversion) |\n| [Comparsion](#comparison) |\n| [Symbols](#symbols) |\n| [Functions](#functions) |\n| [`this`](#this) |\n| [Objects](#objects) |\n| [Maps](#maps) |\n| [Sets](#sets) |\n| [Primitives](#primitives) |\n| [Data Types](#data-types) |\n\n[**Random Notes**](#random-notes)\n\n---\n\n# Promises, async/await\n\n## Callbacks\n\nSome `loadScript` function can be asynchronous (not run now, but later). If we want to use its contents, we can add a callback, and then call `script.onload = () =\u003e callback(script)`. But easily turns into \"callback hell\".\n\n## Promise\n\nPromise:\n1. Takes code that takes time. The rest of our code waits for it, and wants its result once its ready.\n2. When the code produces the promised result, the Promise makes that result available to all the subscribed code.\n\n```\nlet promise = new Promise(function(resolve, reject) {\n  resolve(\"done\");\n\n  reject(new Error(\"…\")); // ignored\n  setTimeout(() =\u003e resolve(\"…\")); // ignored\n});\n\npromise.then(\n\tfunction(result) {},\n\tfunction(resolve) {}\n);\n\n```\n**Resolve** changes the Promise's internal state to fulfilled, and passes result to `.then`. **Reject** runs when promise rejected (`.catch(f) = .then(null, f);`).\n\nHandlers are always asynchronous: code after .then/.catch always end up running before subscribers because of JS's internal execution queue.\n\n### Promise chaining\n\nWe can chain `.then`'s because a `.then` handler returns a Promise. When a `then` returns, it resolves that Promise with the return value. If `then` returns a Promise, we wait until it settles.\n\n## async/await\n\n`async` before a function makes it always return a function (`return 1` is `return Promise.resolve(1)`). `async` allows `await` to be used.\n\n`await` before a promise makes JS wait until that promise settles, then return result or throw error.\n```\nasync function f1() {\n\tlet a = await p1; // wait 2 seconds\n\tlet b = await p2; // wait another 2 seconds\n\treturn a + b\n}\n\nasync function f2() {\n\treturn await p1 + await p2; // wait 2 seconds total (running in parallel);\n}\n```\n\n---\n\n# Advanced Functions\n\n## Closures\n\n### Lexical Environment\n\nEvery _running function_ (so each instance), code block, and script has an associated LE, which stores local variables and a reference to outer LE.\n\nVariables are first searched in the current LE, then outer, outer, etc. LE's don't store old variable values, so when accessing outer values, we use most recent values.\n\n**One call-one LE:** a new LE is created every time a function runs\n\nA closure is function that has `[[Environment]]`, so it remembers its outer variables and can access them.\n\n### `var`\n\n`var` has no block scope, only function-wide or global, so they are visible through blocks (including for loop declarations).\n\n```\n(function () {\n\tconsole.log(salary); // logs undefined because declaration is hoisted\n  var salary = \"5000$\";\n})();\n```\n\n## Scheduling\n\n### Recursive setTimeout\n\nWe can call a `setTimeout` inside another, which will run something regularly. We can also use this to, for instance, request something every 5 seconds, but if the server is overloaded, increase it by a factor of 2 every time.\n\n**Recursive setTimeout guarantees a delay between the executions, setInterval does not.**\nSet Interval:\n![](https://raw.githubusercontent.com/iliakan/javascript-tutorial-en/master/1-js/06-advanced-functions/08-settimeout-setinterval/setinterval-interval.png)\n\nSet Timeout:\n![](https://raw.githubusercontent.com/iliakan/javascript-tutorial-en/master/1-js/06-advanced-functions/08-settimeout-setinterval/settimeout-interval.png)\n\nThe func's execution time consumes a part of the interval. If execution time \u003e interval, func runs again immediately.\n\n### `setTimeout(func, 0)`\n\nZero-timeout scheduling is used to schedule the call \"as soon as possible, but after the current code is complete\". Even if it was `setTimeout(func, 100)` and the current code took \u003e 100ms, func would still wait.\n\n## Throttling and Debouncing\n\nThrottling enforces a maximum number of times a function can be called over time. As in \"execute this function at most once every 100 milliseconds.\" Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in \"execute this function only if 100 milliseconds have passed without it being called.\"\n\n```js\nconst debounce = (fn, delay) =\u003e {\n\tlet timerId;\n\treturn function(...args) {\n\t\tclearInterval(timerId);\n\t\ttimerId = setTimeout(() =\u003e fn.apply(this, args), delay);\n\t};\n};\n\nconst throttle = (fn, delay) =\u003e {\n\tlet inThrottle = false;\n\treturn function() {\n\t\tif (!inThrottle) {\n\t\t\tfn.apply(this, arguments);\n\t\t\tinThrottle = true;\n\t\t\tsetTimeout(() =\u003e inThrottle = false, delay);\n\t\t}\n\t}\n};\n\nfunction throttle2(fn, wait) {\n  let isThrottled = false,\n    lastArgs = null;\n  return function wrapper() {\n    if (isThrottled) {\n      lastArgs = arguments;\n    } else {\n      fn.apply(this, arguments);\n      isThrottled = setTimeout( () =\u003e {\n        isThrottled = false;\n        if (lastArgs) {\n          wrapper.apply(this, lastArgs);\n          lastArgs = null;\n        }\n      }, wait);\n    }\n  }\n}\n\t\t\n\tf() -\u003e wait for a period of time before it can be called again\n```\n\n## Decorators\n\nWraps a function, for instance, to cache the value.\n```\nfunction slow(x) { slow stuff; }\n\nfunction cachingDecorator(func) {\n\t// cache logic...\n\treturn function(x) {\n\t\t// cache logic...\n\t\treturn slow(x);\n\t}\n}\n\nslow = cachingDecorator(slow);\n```\n\nTo set context, use `func.call(context, ...args)`. Or `func.apply(context, [args])`.\n\n---\n\n# Basic JavaScript\n\n## Type Conversion\n\n**String():** null =\u003e “null”. Can never convert Symbols\n\n**Number():** Automatic in mathematical expressions, except “+” (if any operands are strings, becomes string concat)\n- undefined =\u003e NaN, null =\u003e 0, true/false, \n- string =\u003e whitespace removed. empty string =\u003e 0\n- 1 / 0 = Infinity\n\n**Boolean():** intuitively empty =\u003e 0, an empty string, null, undefined and NaN\n\n## Comparison\n\n**String comparison:** compared in dictionary order (letter by letter) _by Unicode value_.\n\n**When different types compared with `\u003c=`, `\u003e=`,** converted to Number.\n\nSame with equality of **only strings, numbers, and booleans**. `null` coerces into `undefined`.\n\nWhen something is `NaN`, any comparison intuitively yields false.\n\n## Symbols\n\n`Symbol(desc)` are unique. Can be hidden properties of objects.\n\nGlobal registry, `Symbol.for(“desc”)` gets (or creates) that symbol to be reused.\n\n`Symbol.keyFor(symbol in global registry)` gets description of that symbol. Must be in global registry.\n\n## Functions\n\n**Function declarations** `function foo(a)` defined first. Visible everywhere in code (or block, which also includes if/else).\n\n**Function expressions** `foo = function(a)` are created when they’re reached.\n\n## `this`\n\n_(defined at run-time)_\n\nIn object methods, has value \"before the dot\": `obj.method()`’s `this` is `obj`.\n\nIf no object, a function's `this` is undefined (in non-use strict, it's `window`)\n\nIf we separate “dot” and method (i.e. `(hi = user.hi)()` instead of `(user.hi)()`), `this` is removed.\n\nArrow method takes `this` from outer function, if any.\n\n## Objects\n\n_For storing keyed collections_\n\n- Object keys are Symbols or strings, or coerced into strings\n\n_Left off at http://javascript.info/object-toprimitive_\n\n## Maps\n\n_For storing keyed collections with keys of any type_\n\n```\nnew Map() creates the map\nmap.set(key, value)\nmap.get(key)\nmap.has(key)\nmap.delete(key)\nmap.clear()\nmap.size\n```\n\n## Sets\n\n_For a collection of unique values_\n\n```\nnew Set(iterable) – creates the set, optionally from an array of values (any iterable will do).\n```\n\nMethods: add, delete, has, clear\n\nAlso a size property.\n\n## Primitives\n\nWhen using object methods, primitives are wrapped in an object, the method is applied, and then the object is destroyed. This ensures primitives are lightweight, but we can still use object properties.\n```js\nlet str = \"Hello\";\n\nstr.test = 5; // creates a test property in the temporary wrapper object\n\nalert(str.test); // error because object was destroyed, and test doesn't exist anymore\n```\n\n## Data Types\n\n**Numbers**\n- 52 of 64 bits can be used to store digits\n- Loss of precision: we can't easily express a fraction in binary. We could use `+(0.1.toFixed(2))`. And when large numbers need more than 52 bits, least significant digits are chopped off.\n\n**Strings*\n- Looped with `for..of`\n- Common methods: `includes`, `indexOf`,\n\n---\n\n# Random Notes\n\n### Garbage collection\n\nJS uses mark-and-sweep. From roots and branch out, marks all refs. Everything unmarked is removed.\n\n### Primitives vs. objects\n\nThe following pattern holds for `Boolean` and `Number`.\n```\nconsole.log(typeof 'foo'); // Logs \"string\"\nconsole.log(typeof String('foo')); // Logs \"string\"\nconsole.log(typeof new String('foo'));  // Logs \"object\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquirrelsquirrel78%2Fjavascript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsquirrelsquirrel78%2Fjavascript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquirrelsquirrel78%2Fjavascript/lists"}