{"id":26052616,"url":"https://github.com/letstayfoolish/js-behind-scenes","last_synced_at":"2025-10-26T11:52:25.668Z","repository":{"id":281149438,"uuid":"944326705","full_name":"letStayFoolish/js-behind-scenes","owner":"letStayFoolish","description":"Small project with key notes of how JavaScript works behind the scenes. Theory backup","archived":false,"fork":false,"pushed_at":"2025-03-27T13:18:36.000Z","size":1880,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-18T12:06:46.482Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/letStayFoolish.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-07T06:43:16.000Z","updated_at":"2025-03-27T13:18:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"dd8e803d-9949-4b73-b06e-7a992e63ea04","html_url":"https://github.com/letStayFoolish/js-behind-scenes","commit_stats":null,"previous_names":["letstayfoolish/js-behind-scenes"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/letStayFoolish/js-behind-scenes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letStayFoolish%2Fjs-behind-scenes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letStayFoolish%2Fjs-behind-scenes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letStayFoolish%2Fjs-behind-scenes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letStayFoolish%2Fjs-behind-scenes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/letStayFoolish","download_url":"https://codeload.github.com/letStayFoolish/js-behind-scenes/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/letStayFoolish%2Fjs-behind-scenes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281099972,"owners_count":26443537,"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","status":"online","status_checked_at":"2025-10-26T02:00:06.575Z","response_time":61,"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":"2025-03-08T06:41:21.116Z","updated_at":"2025-10-26T11:52:25.663Z","avatar_url":"https://github.com/letStayFoolish.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JavaScript behind the scene\n\n## Basics\n\n**JS is high-level language - does not manage sources (memory, processor)**\n\n**Garbage collection - memory management. Cleaning the memory so we do not have to.**\n\n**Just in time compiled language. Converting human-readable code to machine code (zeros) is COMPILING.**\n\n**Multi-paradigm language - Procedural programming, OOP, Functional programming.**\n\n**JS is prototype-based object-oriented language. (e.g. Array.prototype.push)**\n\n**First-class functions - functions are simply treated as variables. We can pass functions into other functions...**\n\n**JS is dynamically typed.**\n\n**Single-threaded. One task at the time.**\n\n**Non-blocking event loop. Takes long-running tasks, executes them in the background, and puts them back in the main thread once they are finished.**\n\n## JavaScript engine and runtime\n\nJS engine - program that **executes** javascript code. Every browser has own JS engine. (**V8 Engine**).\n\nEvery **JS Engine** includes **call stack** and **heap**.\n\nCall stack is where our code is executed. Execution context.\n\nHeap is where **objects are stored**.\n\nFor code to be executed, first we need to compile our code into machine code - **compiling**.\n\n[//]: # (NO PORTABLE FILE as a mid-step)\nSOURCE CODE -\u003e (_compilation_) MACHINE CODE -\u003e (_execution_) Program running\n\n**Compilation**: Entire code is converted into machine code at once, and written to the binary file that can be executed by computer.\n\n**Interpretation** Interpreter runs through the source code and executes it line by line.\n\n![JavaScript Engine](./src/assets/screen-js-01.png)\n\n## Runtime in the browser\n\n![JavaScript Engine](./src/assets/screen-js-02.png)\n\n\n### Inside execution context:\n Variable environment: `let`, `const`, and `var` declarations; Functions, `arguments` object, scope chain, `this` keyword.\n\nArrow functions does not include `this` keyword nor `arguments`.\n\n**CALL STACK** place where execution context get stacked on top of each other, to keep track where we are in execution.\n\nGlobal execution context is pop-out when we close browser window(or tab). Only then program is really finish.\n\n## Scoping\n\n**Scope** - place or environment in which certain variable is **declared**. Where do variables live? There is **global** scope, **function** scope and (ES6)**block** scope.\n\n**Scoping**: How our program variables are **organized** and **accessed**.\n\n**Three type of scopes: The global scope, scope defined by functions (local scope), scopes defined by blocks**\n\nBlock would be anything between curly bracers.\n\n```ts\n{\n    \"block scope...\"\n}\n```\n![scope-screen.png](src/assets/scope-screen.png)\n![scope-screen-02.png](src/assets/scope-screen-02.png)\n\n**Only `let` and `const` variables are block-scoped. Variables defined with `var` are end up in the closest functional scope.**\n\n### Block-scoped: means available only within scope in which they are declared (created).\n\nFunctions are also **block scoped** (only in strict mode).\n\n**Every scope has access to all the variables from all its outer scopes. This is scope chain.**\n\n**When a variable is not in the current scope, the engine looks up in the scope chain until it finds the variable looking for. This is called variable lookup.**\n\n**Scope chain is one-way street. The scope will never have access to the variables of inner scope.**\n\n**The scope chain has nothing to the order in which functions were called.**\n\n```js\n// Variables from global scope are at the top of scope chain!\nconst myName: string = \"Nemanja\"; // Global scope. Variables from global scope are accessible from everywhere!\n\nfunction first(): void {\n    const age = 25;\n    \n    if(age \u003e= 30) {\n        // let and const are block-scoped (ES6)\n        const decade = 2;\n\n        // var is function-scoped. So, in this example first() has access to it and second() as well.\n        var millenium = true;\n    }\n\n    function second(): void {\n        const job = 'teacher';\n\n        // Variables myAge and age are not within this function scope, so it will look up for them\n        // Scope has access to variables from all outer scopes! (scope chain)\n        console.log(`${myName} is ${age} years old and ${job}`)\n    }\n    // Scope chain works only upwards not downwards or sidewards.\n    \n    second()\n}\n\nconst x = first();\n```\n\n## Hoisting\n\n**Hoisting:** Makes some types of variables accessible/usable before they are actually declared.\n\nBefore execution, code is scanned for variable declarations, and for each variable a new property is created in the **variable environment object**.\n\n**Calling function before its declaration - sometimes it seems like functions are moved to the top of scope chain**\n\n**This is not working for `let` and `const` - if we try to call them before its initialization,  error occurs: Can't access before initialization (Temporal Dead Zone). `job = uninitialized`**\n\n**`var` is byproduct. Using `var` in hosting will not throw error, but instead we would get `undefined` as a `var` value. Which makes bugs not that easy to find - that is why we avoid `var`s in modern javascript.**\n\nExample with variables\n```js\nconsole.log(myName); // undefined\nconsole.log(myAge); // Can't access myAge before initialization\nconsole.log(myProfession); // Can't access myProfession before initialization\n\nvar myName = \"Nemanja\";\nconst myAge = 35;\nlet myProfession = \"programmer\";\n```\n\nExample with functions\n```js\nconsole.log(addDecl(4, 5)); // We got the result - because we were able to call function before its declaration. This doesn't work with arrow function and function expression.\nconsole.log(addExpr(1, 7)); // Error: Can't access the function before initialization\nconsole.log(addArrow(8, 5)); // Error: Can't access the function before initialization\n\n\nfunction addDecl(a: number, b:number){\n    return a + b;\n}\n\nconst addExpr = function(a: number, b:number){\n    return a + b;\n}\n\nconst addArrow = (a: number, b:number) =\u003e  a + b;\n```\n\nExample to show why should we avoid using `var`\n```js\n\nif(!cartProducts) deleteAllProductsFromCart(); // In this case deleteAllProductsFromCart() is called, because `cartProducts` is set to undefined (due to how hoisting works with vars).\n\n// Our products would be removed from cart even though cartProducts are set tot 10;\nvar cartProducts = 10;\n\nfunction deleteAllProductsFromCart() {\n    console.log(\"All products deleted from cart\");\n}\n``` \n## How `this` Keyword Works\n\n* Within method - `this` is pointing to the Object which calling this method;\n* Simple function call - this is `undefined`;\n* Arrow functions - `this` of surrounding function (lexical this);\n* Event listener - `this`: DOM element that handler is attached to;\n* `this` does **NOT** point to the function itself, and also **NOT** to its variable environment!\n\n```js\nconsole.log(this); // pointing to the top Object Window\n\nconst addExpr = function (a: number, b: number) {\nconsole.log(this); // undefined (in sloppy mode it would point to Window Object, but not if we use strict mode);\n\n    return a + b;\n}\n\naddExpr(1, 6);\n\nconst calcExpr = (a: number, b: number) =\u003e {\nconsole.log(this); // within arrow functions, `this` is point to (parent) Window Object; Depends on what `this` word is in parent scope\n// in this case `this` will point what this means in (parent) global scope - Window Object\nreturn a + b;\n}\n\ncalcExpr(5, 5); // Arrow function\n\nconst user = {\n    name: \"Nemanja\",\n    age: 35,\n    profession: \"programmer\",\n    sayHello: function () {\n    console.log(`Hello, my name is ${this.name}`); // this will point to the Object user (user.name);\n    }\n}\n\nuser.sayHello();\n```\n\nOne more example of how to use `this` keyword within regular functions and arrow functions:\n```js\nconst user = {\n    name: \"Nemanja\",\n    surname: \"Karaklajic\",\n    age: 35,\n    profession: \"programmer\",\n    sayHello: function () {\n        console.log(`Hello, my name is ${this.name}`); // this will point to the Object user (user.name);\n\n        // Solution 1\n        // const self = this;\n        // const getFullName = function() {\n        //     console.log(self)\n        //     console.log(`Fullname: ${self.name} ${self.surname}`)\n        // }\n\n        // Solution 2\n        // Introduce this within arrow function\n        const getFullName = () =\u003e {\n            console.log(this)\n            console.log(`Fullname: ${this.name} ${this.surname}`)\n        }\n\n        getFullName();\n    }\n}\n\nuser.sayHello();\n```\n\n**Primitive** type variables are stored in **call stack**. Identifier is pointing to the `address` of call stack's piece of memory, which has its own `value`. Addresses are immutable, so if we change the value, that means that new address is created, and our variables is stored with that new address (and new value).\n\n**Reference** type values (objects) are stored in the **Heap** memory. Identifier is pointing to piece of memory (_call stack_), which points to the object that is in _heap_ memory by using memory address as its value.\nThe piece of memory in the _call stack_ has a reference to the piece of memory in the _heap_ which holds `object`. That's why object are called **reference type**. Heap memory is almost unlimited, that is whu we store object there, instead of stack.\n\n```ts\ntype ObjectType = {\n    age: number,\n    firstName: string,\n    lastName: string,\n    greet?: () =\u003e void,\n}\n\nconst meObj: ObjectType = {\n    age: 22,\n    firstName: \"MyName\",\n    lastName: \"MyLastName\",\n}\n\nconst myFriend = meObj; // by this we are just copping the reference which is pointing to the same object's value;\n\nmyFriend.age = 35;\n\nconst johnObj = Object.assign({}, meObj); // (shallow copy)\njohnObj.age = 44;\njohnObj.greet = function() {console.log(this.firstName)}\n\nconsole.log(meObj)\nconsole.log(myFriend)\nconsole.log(johnObj)\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fletstayfoolish%2Fjs-behind-scenes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fletstayfoolish%2Fjs-behind-scenes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fletstayfoolish%2Fjs-behind-scenes/lists"}