{"id":21182692,"url":"https://github.com/guilhermebkel/advanced-javascript-concepts-study","last_synced_at":"2025-03-14T19:44:14.412Z","repository":{"id":165592986,"uuid":"243602732","full_name":"guilhermebkel/advanced-javascript-concepts-study","owner":"guilhermebkel","description":":dragon_face: A deep study about advanced javascript topics","archived":false,"fork":false,"pushed_at":"2021-01-17T12:19:54.000Z","size":20,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-21T12:33:13.561Z","etag":null,"topics":["engine","garbage-collection","javascript","javascript-concepts","javascript-runtime","v8-javascript-engine"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/guilhermebkel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2020-02-27T19:47:03.000Z","updated_at":"2024-03-01T09:55:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"7897c5ff-0333-44e3-8e88-281c041f1060","html_url":"https://github.com/guilhermebkel/advanced-javascript-concepts-study","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guilhermebkel%2Fadvanced-javascript-concepts-study","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guilhermebkel%2Fadvanced-javascript-concepts-study/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guilhermebkel%2Fadvanced-javascript-concepts-study/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guilhermebkel%2Fadvanced-javascript-concepts-study/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guilhermebkel","download_url":"https://codeload.github.com/guilhermebkel/advanced-javascript-concepts-study/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243639330,"owners_count":20323505,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["engine","garbage-collection","javascript","javascript-concepts","javascript-runtime","v8-javascript-engine"],"created_at":"2024-11-20T17:57:41.279Z","updated_at":"2025-03-14T19:44:14.406Z","avatar_url":"https://github.com/guilhermebkel.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# advanced-javascript-concepts-study\n:dragon_face: A deep study about advanced javascript concepts\n\n## Summary\n\n- [ How the browser understands javascript code ](#how-the-browser-understands-javascript)\n- [ Stack and Heap Memory ](#stack-and-heap-memory)\n- [ Garbage collection ](#garbage-collection)\n- [ Main causes of memory leak ](#main-causes-of-memory-leak)\n- [ Javascript runtime ](#javascript-runtime)\n- [ Hoisting ](#hoisting)\n- [ Function Invocation ](#function-invocation)\n- [ Strict Mode ](#strict-mode)\n- [ Block scope ](#block-scope)\n- [ Manipulating 'this' keyword ](#manipulating-this-keyword)\n- [ Javascript types ](#javascript-types)\n- [ Type coercion ](#type-coercion)\n- [ Closures and Memory ](#closures-and-memory)\n- [ Constructor Functions ](#constructor-functions)\n- [ Pure Functions ](#pure-functions)\n- [ Closure Functions ](#closure-functions)\n\n\u003ca name=\"javascript-foundation\"\u003e\u003c/a\u003e\n\n## How the browser understands javascript code\n\nThere is a **Engine** which is capable of making some work to make the javascript code to be compiled into machine code during its execution and so interpreted dynamically.\n\nEvery browser has its own engine, today the most famous is called **V8 Engine** and it is used by Google Chrome and new versions of Internet Explorer.\n\nBelow you can see the steps followed by the **Engine** in order to make the javascript code interpretable by computer:\n\n- ```Parser```\n\t- The javascript code is parsed based on its syntax (variable declarations, function declarations, etc) into a **AST - Abstract Syntax Tree** (it is basically a JSON of the code formated into a tree).\n\nAfter the step above, the following ones happen at the same time:\n\n- ```Interpreter```\n\t- Turns the **AST** into **Bytecode** (not a machine code, but executable with engine help) that gets executed by the computer on the fly (it is a work around to make the code to be executed as fast as possible by the browser, since it is not actually optimized and a real machine code but is executable anyway).\n\n- ```Compiler```\n\t- While the **Interpreter** is running, it makes optimizations on the created **Bytecode**. After making the needed optimizations, it replaces the **old non-optimized Bytecode** with the new changes.\n\nSo, with the steps above (called JIT Compiler - Just In Time Compiler), the code gets executed on the fly while making needed optimizations to improve the application speed.\n\n\u003ca name=\"stack-and-heap-memory\"\u003e\u003c/a\u003e\n\n## Stack and Heap Memory\n\nThe common declarations below will be done with **Stack Memory**:\n```js\n// declaring numbers and strings\nconst x = 1;\nconst y = \"mota\";\n\n// calling a function in the simple way\nfunction something() {\n\tconsole.log(\"something\");\n};\nsomething();\n```\n\nAnd the following ones will be done with **Heap Memory**:\n```js\n// object declaration\nconst user = {\n\tname: \"mota\"\n};\n\n// using the 'new' keyword to call a function\nfunction userName(userName) {\n\tthis.userName = userName;\n};\nnew userName(\"mota\");\n\n// using the 'new' keyword to call a class\nclass UserLastName {};\nnew UserLastName();\n```\n\n\u003ca name=\"garbage-collection\"\u003e\u003c/a\u003e\n\n## Garbage collection\nIn Javascript, the garbage collection occurs automatically (since it is a manual job on another languages like C).\n\nBasically, the garbage collector works on variables that are not pointing to any memory space, per example:\n\n```js\nvar user = {\n\tname: \"Mota\",\n\tlastName: \"Bromonschenkel\"\n}\n\nuser = 1\n\n// The garbage collector will clear the last value and keep the new one\n```\n\n\u003ca name=\"main-causes-of-memory-leak\"\u003e\u003c/a\u003e\n\n## Main causes of memory leak\n\nA memory leak occurs when we start using some space in memory and it doesn't get back to us with the garbage collector help.\n\nIn generally there are mainly causes of memory leak, per example:\n- Global variables\n- Event listeners\n- setInterval functions\n\n\u003ca name=\"javascript-runtime\"\u003e\u003c/a\u003e\n\n## Javascript runtime\n\nGenerally in Javascript we have three different environments which are needed to run the code:\n\n1. **Call Stack / Memory Heap:** Common javascript code\n```js\nconsole.log(\"Call Stack / Memory Heap\")\n```\n\n2. **Job Queue - Microtask Queue:** Asynchronous code\n```js\nPromise.resolve(console.log(\"Job Queue - Microtask Queue\"))\n```\n\n3. **Callback Queue - Task Queue:** Browser functions derived from the global object\n```js\nsetTimeout(() =\u003e console.log(\"Callback Queue - Task Queue\"), 0)\n```\n\n\nSo if we run the following code:\n```js\nsetTimeout(() =\u003e console.log(\"Callback Queue - Task Queue\"), 0) // Third\n\nPromise.resolve(console.log(\"Job Queue - Microtask Queue\")) // Second\n\nconsole.log(\"Call Stack / Memory Heap\") // First\n```\n\n1. The ```setTimeout(() =\u003e console.log(\"Callback Queue - Task Queue\"), 0)``` gets into the **Web API**.\n\n2. The ```Promise.resolve(console.log(\"Job Queue - Microtask Queue\"))``` gets into the **Job Queue**.\n\n3. The ```console.log(\"Call Stack / Memory Heap\")``` gets into the **Call Stack** and gets executed.\n\n4. The **Event Loop** do the following:\n\t- Is the Call Stack empty?\n\t\t- **True**: Is there any job on **Job Queue**?\n\t\t\t- **True**: ```Promise.resolve(console.log(\"Job Queue - Microtask Queue\"))``` is moved from the **Job Queue** to the **Call Stack** and gets executed.\n\n5. The **Event Loop** do the following:\n\t- Is the Call Stack empty?\n\t\t- **True**: Is there any job on **Job Queue**?\n\t\t\t- **False**: Is there any job on **Web API**?\n\t\t\t\t- **True**: ```setTimeout(() =\u003e console.log(\"Callback Queue - Task Queue\"), 0)``` is moved from the **Web API** to the **Callback Queue** and gets executed.\n\n\n\u003ca name=\"hoisting\"\u003e\u003c/a\u003e\n\n## Hoisting\n\nA hoist occurs when we call a variable/function before defining it (and it works without errors), because the Javascript Engine reads all code during the creation phase, asks for some space on the heap memory to put some declared variables/functions (in order to improve first time execution speed) and then executes it. Below you can see an example of hoisting:\n```js\nconsole.log(lastName) // Prints 'mota'\nvar lastName = \"mota\"\n\nconsole.log(getFirstName()) // Prints 'guilherme'\nfunction getFirstName() {\n\treturn \"guilherme\"\n}\n```\n\nIf you want to avoid hoisting, you can do the following:\n```js\nconsole.log(firstName) // Error 'firstName' is not defined'\nconst firstName = \"guilherme\"\n\nconsole.log(lastName) // Error 'lastName' is not defined'\nlet lastName = \"mota\"\n\nconsole.log(getNumber()) // Error 'getNumber' is not defined'\n(function getNumber() {\n\t\treturn 1\n})\n```\n\n\u003ca name=\"function-invocation\"\u003e\u003c/a\u003e\n\n## Function Invocation\n\nWe can define a function as an expression or a declaration. The main difference between them is that **Function Expressions** get defined during the code execution and **Function Declarations** get defined during the code parsing.\n\n```js\n// Function Expression\nconst printName = () =\u003e {\n\tconsole.log(\"Guilherme\")\n}\n\n// Function Declaration\nfunction printLastName() {\n\tconsole.log(\"Mota\")\n}\n```\n\n\u003ca name=\"strict-mode\"\u003e\u003c/a\u003e\n\n## Strict mode\n\nIf we run the following code, it will not trigger any error:\n\n```js\nfunction test() {\n\ttested = 1\n}\n\ntest() // Runs without errors\n```\n\nIn order to prevent it from happening, we can add the 'use strict' keyword that will force some ECMAScript validations:\n\n```js\n'use strict'\n\nfunction test() {\n\ttested = 1\n}\n\ntest() // Triggers error: 'tested is not defined'\n```\n\n\u003ca name=\"block-scope\"\u003e\u003c/a\u003e\n\n## Block scope\n\nWhen we create some statement using brackets, we're only able to access variables if they are declared with 'var' keyword\n\n```js\n// Works\nif (5 \u003e 4) {\n\tvar a = 1\n}\nconsole.log(a)\n\n// Does not work\nif (5 \u003e 4) {\n\tconst a = 1\n}\nconsole.log(a)\n\n// Does not work\nif (5 \u003e 4) {\n\tlet a = 1\n}\nconsole.log(a)\n\n```\n\n\u003ca name=\"manipulating-this-keyword\"\u003e\u003c/a\u003e\n\n## Manipulating 'this' keyword\n\nWhen dealing with **this** keyword, we have the following methods (that are created during the function instancing): **call, apply, bind**.\n\n```js\nconst wizard = {\n\tname: \"Merlin\",\n\thealth: 100,\n\theal(firstHp, secondHp) {\n\t\tthis.health += firstHp + secondHp;\n\t}\n}\n\nconst archer = {\n\tname: \"Robin Hood\",\n\thealth: 30\n}\n\n// Use function 'heal' of wizard on archer\n// passing '100' as the function argument\nwizard.heal.call(archer, 100, 100) // Heals by 200\nwizard.heal.apply(archer, [100, 100]) // Heals by 200\n\n// Returns the updated method, without executing it\narcher.heal = wizard.heal.bind(archer, 100)\narcher.heal(100) // Heals archer by 200 hp\n```\n\n\u003ca name=\"javascript-types\"\u003e\u003c/a\u003e\n\n## Javascript types\n\n- Primitive Types: Usually represents a single type on memory\n```js\ntypeof 5 // number\ntypeof true // boolean\ntypeof \"mota\" // string\ntypeof undefined // undefined\ntypeof null // object\ntypeof Symbol(\"mota\") // symbol\n```\n\n- Non Primitive Types: Does not represent a type on memory\n```js\ntypeof {} // object\ntypeof [] // object\ntypeof function(){} // function (but it is actually an object)\n```\n\nEven with these multiple types, we can say that **almost everything in Javascript** is an **object**, since the wrappers used to create other types are objects, per example:\n```js\n// true has property to string even being an boolean\ntrue.toString() // 'true'\n\n// Because the above is the same as using the boolean wrapper that is an object\nBoolean(true).toString() // 'true'\n```\n\nObs: If a data is explicitly of type **object** (usually we can guarantee it using the 'typeof' keyword), it will be instanced on **Heap Memory** and so **Passed by Reference** to methods.\n```js\nconst firstCat = { name: \"Bob\" }\n\nconst secondCat = firstCat\n\nsecondCat.name = \"Ana\"\n\nconsole.log(firstCat.name) // 'Ana'\nconsole.log(secondCat.name) // 'Ana'\n```\n\n\u003ca name=\"type-coercion\"\u003e\u003c/a\u003e\n\n## Type coercion\n\nType coercion means the own language converts types to make use of statements, etc.\n\nPer example, everything in Javascript is considered **true** except for the following:\n```js\nfalse\n0\n\"\"\nnull\nundefined\nNaN\n```\n\n\u003ca name=\"closures-and-memory\"\u003e\u003c/a\u003e\n\n## Closures and Memory\n\nWe're able to reuse functions without having to create it in memory after every call. It can be done with help of **closure**.\n\n```js\nfunction heavyDuty(index) {\n\tconst bigArray = new Array(7000).fill(\"mota\")\n\n\tconsole.log(\"Created: heavyDuty\")\n\n\treturn bigArray[index]\n}\n\nfunction heavyDutyClosure() {\n\tconst bigArray = new Array(7000).fill(\"mota\")\n\n\tconsole.log(\"Created: heavyDutyClosure\")\n\n\treturn function(index) {\n\t\treturn bigArray[index]\n\t}\n}\n\nheavyDuty(500)\nheavyDuty(600)\nheavyDuty(700)\n\nconst getHeavyDutyClosure = heavyDutyClosure()\n\ngetHeavyDutyClosure(500)\ngetHeavyDutyClosure(600)\ngetHeavyDutyClosure(700)\n\n/*\n * The console.log will look like:\n *\n * Created: heavyDuty\n * Created: heavyDuty\n * Created: heavyDuty\n * Created: heavyDutyClosure\n */\n```\n\n\u003ca name=\"constructor-functions\"\u003e\u003c/a\u003e\n\n## Constructor Functions\n\nSince functions in Javascript has inherit its prototype from object (what makes them a special type of object), we can create objects by using the \"new\" keyword on function as you can see below:\n\n```js\nfunction Elf(name, weapon) {\n\tthis.name = name\n\tthis.weapon = weapon\n}\n\nElf.prototype.attack = function() {\n\treturn \"Attack with \" + this.weapon\n}\n\nconst peter = new Elf(\"Peter\", \"stones\")\nconsole.log(peter.attack()) // output: Attack with stones\n\nconst sam = new Elf(\"Sam\", \"fire\")\nconsole.log(sam.attack()) // output: Attack with fire\n\n/**\n * In case we want to use a function inside a method while accessing\n * the \"this\" keyword, we have to add the \"this\" to a new variable\n * since a common function in Javascript is considered an object\n * and the \"this\" keyword inside it will refer to this function itself.\n */\nElf.prototype.build = function() {\n\tconst self = this\n\n\tfunction building() {\n\t\treturn self.name + \"builds a house\"\n\t}\n\n\treturn building()\n}\n/**\n * We can make a simple workaround to the problem above by using\n * arrow functions, since them, different of common functions,\n * don't create an own scope, so it inherits the scope from the\n * parent function.\n */\nElf.prototype.build = function() {\n\tconst building = () =\u003e {\n\t\treturn this.name + \"builds a house\"\n\t}\n\n\treturn building()\n}\n```\n\n\u003ca name=\"pure-functions\"\u003e\u003c/a\u003e\n\n## Pure Functions\n\nWe call pure functions the ones which don't cause side effects all around the code. They are the core of **functional programming**.\n\n```js\n// Cause side-effects\nconst array = [1, 2, 3]\nfunction removeLastItem(arr) {\n\tarr.pop()\n}\nremoveLastItem(array)\nconsole.log(array) // [1, 2]\n\n// Doesn't cause any side-effects\nconst array = [1, 2, 3]\nfunction removeLastItem(arr) {\n\tconst copiedArray = [...arr]\n\tcopiedArray.pop()\n\treturn copiedArray\n}\nconsole.log(removeLastItem(array)) // [1, 2]\nconsole.log(array) // [1, 2, 3]\n```\n\n\u003ca name=\"closure-functions\"\u003e\u003c/a\u003e\n\n## Closure Functions\n\nClosure is such a way to create HOF (High order functions) that share **state** (variables, methods, etc) with **children functions**, what means that the children can change state of its parents.\n\n```js\nconst closure = function() {\n\tlet count = 0\n\n\treturn function increment() {\n\t\tcount++\n\t\t\n\t\tconsole.log(count)\n\t}\n}\n\nconst incrementFunction = closure()\n\nincrementFunction() // 1\nincrementFunction() // 2\nincrementFunction() // 3\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguilhermebkel%2Fadvanced-javascript-concepts-study","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguilhermebkel%2Fadvanced-javascript-concepts-study","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguilhermebkel%2Fadvanced-javascript-concepts-study/lists"}