Notes on JavaScript: Understanding the weird parts

I am learning to code. First up, JavaScript! I am also blogging my notes to help me better understand the concepts. Hopefully other humans might find this helpful too. If you are a human who knows a lot about JavaScript or programming in general and find a mistake in these notes, please ping me! (If you are not a human i’ve so many questions for you. Also ping me!)

These notes are taken after watching an amazing course by Anthony Alicea. Note: this is an intermediate level course and most of the examples come straight out of the course.

Lets get to it.


I. Execution Contexts and Lexical Environments

Syntax Parser: A program that reads/scans your code and determines the validity of your code’s grammar according to the specific rules of the JavaScript language.

Lexical Environment: Where your code sits physically. Where is it written and what surrounds it? The syntax parser cares about the lexical environment in order to determine what the code does and where things will live in memory and how they relate to each other.

Execution Context: There could be lots of lexical environments in your code. An execution context is a wrapper that helps manage the code that is currently running. Any time you execute or invoke a function, a new execution context is created.

Two Phases of the Execution context: are the Creation phase and Execution phase. In the Creation phase the Global Object Window and ‘this’ are setup in memory and a reference to the outer environment is created. In the same creation phase the parser runs through your code and recognizes where variables and functions are created. This process of setting up memory space for variables and functions is called Hoisting. This means when the code starts to execute line by line during the Execution phase, it can access the variables and functions from memory. However, variables and functions are hoisted in a different manner. A function is ‘hoisted’ in its entirety into a memory space, while a variable initialized asundefined during creation phase. A variable’s value is then assigned during the actual execution phase.

 [gist https://gist.github.com/tamg/bbb3f64770374b73fab41d27f2076732#file-executioncontext-js]

The Global Environment: It is the base execution context. It is accessible everywhere to everything in your code. If you are not inside a function you are in the global environment. The outer environment outside of the Global is null.

The Global Object and ‘this’: the JavaScript engine creates two things in the global execution context (if running in the browser): A Global Object Window and a global variable ‘this’ that points to Window.

Single threaded execution: JavaScript runs on a single thread. This means, that only one command runs at a time, executed one line at a time.

The Execution Stack: Any time you execute or invoke a function, a new execution context is created and put on the Execution stack. Then the engine will go through the two execution phases: Creation & Execution. Once each line is executed inside the function, the execution context is ‘popped off’ the execution stack.

 [gist https://gist.github.com/tamg/13e3adf79e4fd6d4c83b94a129b8012d#file-executionstack-js]

Variable Environment: refers to where the variables live and how they relate to each other in memory. Every execution context has its own variable environment. The variable environment for the global execution context is the global object i.e. Window .

The Scope chain: every execution context has its own this variable, a variable environment and a reference to its outer environment. When you ask for a variable inside an execution context and the variable doesn’t exist inside that context, the JavaScript engine will look at the outer reference to find the variable. The outer environment of an execution context is determined by looking at where the function is lexically (physically) sitting in the code. The process of searching through this chain of references to outer environments across the execution stack is called the scope chain.

 [gist https://gist.github.com/tamg/14e5a06f15a388a626ea823f19f27b9e#file-scope_chain-js]

II. Types and Operators

Dynamic Typing: JavaScript is a dynamically typed language. The type of data a variable holds is figured out while the code is running(opposite of static type).

Primitive Types: A data that represents a single value. There are 6 primitive types in JavaScript. Undefined, Null, Boolean, String, Number, Symbol(ES6).

Double Equality (==) vs Strict Equality (===): double equals will perform coercion when comparing two things while strict equality compares two things without coercion of types.

 [gist https://gist.github.com/tamg/91b3a7632de3e2e75647f2466a2bcc5a#file-equality-js]

Coercion: Converting a value from one type to another.

 [gist https://gist.github.com/tamg/20e6547f944990bcd0d06be49419d92d#file-coersion-js]

III. Objects and Functions

Property vs Method: In an Object literal, if the value of a key is a primitive then we call that key a property. If the value is a function then we call it a method.

First Class Functions: Everything you can do with other types you can do with functions, like assigning them to variables, pass them around or create them on the fly. Essentially Functions are Objects. It also means that functions can also have properties! In fact, when a function executes, the JavaScript engine creates the this keyword and attaches it to the function as a property.

Function Statements vs Expressions: When a function statement is run, it doesn’t return a value. It is just stored in memory. A function expression returns a value which can in turn be saved in a variable. Thus, a function expression, just like variables, can not be invoked before creation.

 [gist https://gist.github.com/tamg/54714fa21030fc5ff3c3ef151b3ced10#file-statement_expression-js]

Arguments: the keyword arguments is automatically available to us inside a function and contains an array like list of all the values of all the parameters passed to a function.

 [gist https://gist.github.com/tamg/5c54863552e7a5b17b0999db36272327#file-arguments-js]

By Value vs By Reference: The way JavaScript passes a value is different for a primitive vs an object. By value means we are creating a new copy of the value, while By reference means we are just pointing to the same location in memory. Primitives are passed by value while objects are passed by reference.

 [gist https://gist.github.com/tamg/5969f18037da520e853a84ace0846dd5#file-byvalue_byref-js]

‘this’: a little recap first. When an execution context is created three main things happen: a variable environment is created, a reference to the outer environment is created and the JavaScript engine gives us a ‘this’ variable. The this keyword will then be pointing at a different object depending on where the function is and how the function is invoked. Some of these scenarios are listed below.

 [gist https://gist.github.com/tamg/69a418fc9e6ff59d7ce4cdd62e4edefb#file-this-js]

Immediately Invoked Function Expression (IIFE): is a function that is invoked immediately after being created. Since variables used inside an IIFE are not visible outside of its scope, IIFE is usually implemented as a way to avoid interfering with the global namespace.

 [gist https://gist.github.com/tamg/45c74458c718ae75f02c164d4ac8062b#file-iife-js]

Closures: We have seen that a function execution context has access to its outer environment via the scope chain. If a function(inner) is located inside another function(outer), the inner function has access to the variables inside the outer function even after the outer function has returned and is popped off the execution stack. This feature is known as closure. This means that when a function in JavaScript executes, it have access to the same scope chain that was available when the function was created!

 [gist https://gist.github.com/tamg/e698f3d7c1b9f5c2a4885c30290820f8#file-closure-js]

Clousures and Callbacks: an area where we use clousures a lot is in callbacks.

 [gist https://gist.github.com/tamg/d3074e60eb87cd86f34ea7f96fef6d61#file-clousurescallbacks-js]

Call, Apply and Bind: As we have seen before functions are objects in JavaScript. As such functions can have methods. Call, Apply and Bind are built in methods that exist on all functions. We have also seen that how the this keyword can be tricky to pinpoint what it points to. Call, Apply and Bind are methods that allow us to explicitly set what this should refer too. While Call and Apply invoke the function immediately, Bind returns a copy of the function that when executed at a later time will point to the correct context of the original function.

 [gist https://gist.github.com/tamg/861ed62fa3a8a5001632d4e79ab38f42#file-callapplybind-js]

Function borrowing: using bind, call and apply we can start to use one objects methods on another object.

 [gist https://gist.github.com/tamg/d4663ea7f64ac6f70d4b87636db69cfe#file-fnborrowing-js]

 

IV Object-Oriented JS and Prototypal Inheritance

The Prototype Chain: by default all objects in JavaScript have a prototype property accessed through a special reference object called _proto_. The process of searching through a series of prototype reference objects is called the prototype chain.The final link in this chain is null which has no prototype.

Function Constructor: is a regular function that is used to construct objects with the new keyword. The this variable inside the constructor points to a new empty object, and that object is returned from the function automatically. Any object created from a function constructor has access to any features added to the prototype property of the function constructor via the prototype chain. This is why we usually designate object properties inside function constructors but add features to the object via the function constructor’s prototype, which is much more efficient.

 [gist https://gist.github.com/tamg/3eb0571851de902be1c1ebf999e5842e#file-fnconstructor-js]

Object.create: creates a new object by taking an object as its parameter. The newly created object is empty and its prototype property points to the object prototype passed as a parameter. We create properties and methods on the newly created object by overriding it ourselves. As such, object.create allows us to create new objects with pure prototypal inheritance.

 [gist https://gist.github.com/tamg/5089812276139d3be2e87269a73f9fce#file-objectcreate-js]

Whew! That’s it!

Just Kidding! Will add more definitions and examples of concepts as I learn more about JavaScript. Thanks for reading and please comment if you find a mistake on my notes 🙏🏽