Lets get to it.
I. Execution Contexts and Lexical Environments
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
‘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 as
undefined during creation phase. A variable’s value is then assigned during the actual execution phase.
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
Window and a global variable
‘this’ that points to
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.
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.
The Scope chain: every execution context has its own
II. Types and Operators
Double Equality (==) vs Strict Equality (===): double equals will perform coercion when comparing two things while strict equality compares two things without coercion of types.
Coercion: Converting a value from one type to another.
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.
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.
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.
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.
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.
Clousures and Callbacks: an area where we use clousures a lot is in callbacks.
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.
Function borrowing: using bind, call and apply we can start to use one objects methods on another object.
IV Object-Oriented JS and Prototypal Inheritance
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.
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.
Whew! That’s it!