Notes based on course ‘JavaScript: Understanding the Weird Parts’ & others.

Upcoming:

  • Code snippets with examples.

Github Repository

Section 2: Execution Context and Lexical Environments

  • JavaScript is a programming language that abstracts you away from how the browser/computer works.

  • Understand how the tool is functioning to write advance JS code.

  • Syntax parsers: interpreter or compiler that translates JS code into machine readable code.

    • This process also determines meaning (value) of variables and checks if grammar is valid.
  • Execution context: wrapper to help manage lexical environments and check what code is running based on execution context.

  • Lexical environment: the scope of the code, where something sits physically in the code you write.

  • name/value pairs: a name which maps to a unique value. A name can be defined many times however it can only hold one value per execution context.

  • Object: collection of name/value pairs.

Global Execution Context

  • Two keywords created by JS engine, ‘global object’ and ‘this’ keyword.

  • Can be accessed anywhere in code.

  • Both ‘global object’ and ‘this’ are equal.

  • They can be the browser tab in use or another server generated context environment.

Hoisting

  • Values and functions can be invoked before they are defined.

  • Different procedure for variables and functions.

    • Functions are placed entirely in physical memory.

    • Variables are initially set as ‘undefined’.

  • Difference between not defined and undefined.

    • If variable is not defined (does not exist in memory space or scope) an error will be raised.

    • Undefined is used as a default placeholder for all variables.

Execution Context

Performed in two parts, creation phase and execution phase.

Creation phase

  • In the first phase the JS engine sets up memory space for variables and functions (hoisting) while creating the ‘global context’, ‘this’ and other environments.

  • Variables are named but not defined in memory and given the type ‘undefined’.

  • Functions however are entirely placed in memory.

Execution phase

  • Execution context reads code line by line.

  • Performs assignment on variables and determines their meaning/value.

  • All values are initially undefined, undefined is a special value used by JS and is not the same as ‘not defined’. Not defined means no variable with that name exists in this execution context (memory space).

Single Threaded, Synchronous Execution

  • Single threaded: one command at a time.

  • Synchronous execution: one at a time, one line of code executed in order.

  • The above describes the behaviour of JS.

Variable Environment

  • Where the variables live and how they relate to each other in memory.

Scope

  • Where a variable is available in your code and if it’s truly the same variable or a new copy.

  • Each execution context (scope) has its own variable environment (memory space).

  • Every time a function is called a new execution context is created with its own unique variable environment.

  • Every execution context has a reference to its outer environment.

    • This other environment order is determined by the lexical location of the code.

Scope Chain

  • Going down the outer environment reference link chain until variable is found.

  • Chain is links of outer environment references.

  • Where a function sits lexically determines its outer environment as execution contexts are stacking up.

Those that learn how things really work under the hood, solve problems better and are better coders overall in the end.

Let

  • Uses block scoping and are only available inside declared block.

  • Variables are placed in memory however not used until the line of code is run during the execution phase that declares the variable.

Asynchronous

  • Occurring at the same time.

Event Queue

  • Stack full of events, notifications of events that might be happening are placed in the queue.

  • Each event processed creates its own execution context to be processed in execution stack.

  • Execution stack must be empty before event queue can be processed.

  • The browser will asynchronously put items in event queue while JS synchronously executes them line by line.

Section 3 Types and Operators

Dynamic Typing

  • Don’t specify variable type, the engine determines that at runtime/execution.

  • Js is dynamic typing.

Static Typing

  • Specify the type of the variable at declaration.

Primitive Types

  • A type of data that represents an atomic (single) value (not an object).
  1. Undefined: represents the lack of existence.

  2. Null: represents the lack of existence.

  3. Boolean: true (1) or false (0) values.

  4. Number: floating point numbers.

  5. String: a sequence of characters wrapped in ‘ ’ or “ “.

  6. Symbol: used in ES6 (new ES6 type).

Operators

  • A special function that is syntactically (written) differently.

  • Generally they take two parameters and return one.

  • Index notation: the function name (operator) is written between the two parameters.

Operator Precedence

  • Which operator function gets called first.

  • Functions are called in order of precedence.

  • Higher precedence wins (BODMAS).

Operator types

  • Urinary takes single parameter.

  • Binary takes two parameters.

  • Ternary takes three parameters.

Associativity

Coercion

  • Js engine will try to convert one value type to another. Given an operation between two different types the JS engine will make a best guess in converting them into the same type.

  • Anything that represents a lack of existence can be converted into false or 0.

  • The logic OR (   ) operator will return the first value that can be converted to true e.g: ‘undefined   “hello” = “hello”’.

Section 4 Objects and Functions

Objects

  • Objects and functions are very similar in JS.

  • Objects are collections of name value pairs.

  • Objects can have the following properties (members) connected to it:

    • Primitive property.

    • Object property.

    • Functions are called methods inside objects.

    • Objects have reference to the memory space/address of the property/method.

  • Object property accessors:

    • Square bracket notation [].

    • Dot notation ‘.’.

    • Use the above to access members of the object or attach new properties to the object.

    • Syntax ObjectName.member or ObjectName[Member]

  • Object Literal

    • Syntax of declaring a new object.

    • Var person = { … };

Namespace

  • A container for variables and functions.

  • Not available in JS but can be overcome with the use of objects as containers/namespaces.

JSON (Java Script on Notation)

  • JSON is a subset of object literals, has stricter rules but not the same.

  • JSON is a standardisation of passing data across the network.

  • JSON valid is always valid JS object literals but not all object literal is JSON valid.

  • JSON.Stringify() to convert to JSON.

  • JSON.Parse() to convert string into object.

First Class Functions

  • Functions are objects.

  • Everything you can do with other types you can do with functions.

    • Assign them to a variable, pass them around, create them on the fly.

    • Attaching primitives, objects and other functions to a function.

  • Two specific features of JS:

    • Anonymous functions: function in JS don’t need a name.

    • Code property: the physical (written) code of a function is attached as an invokable property of the function creating execution context.

Function Expression

  • Is a unit of code that results in a value (executes and returns a value).

  • Does not require result to be assigned to a variable.

  • Var anonGreet = function() { console.log(‘Hi’); } anonGreet();

  • Function expression will cause error as it is hoisted as undefined unless immediately invoked.

Function Statement

  • Execute and stored in memory, does not return a value.

  • Can be called before declaration (because of hoisting).

  • Reference functions with variable names.

  • function greet() { console.log(‘Hi’); }

Good code is being clear and understandable while at the same time minimising the amount of code to write.

Passing by Value

  • Passing, referencing or setting qual one value to another by copying the value.

  • Two seperate spaces in memory.

  • Applies to all primitives.

  • Equal (=) operator sets up a new memory space (new address).

Passing by Reference

  • Two variables point to or reference the same space in memory.

  • All objects, function and their parameters act this way.

  • One change to a value in memory space will affect all references to it.

Mutate

  • To change something.

Immutable

  • Means it cannot be changed

This Keyword

  • On every new context creation a ‘this’ keyword variable is created.

  • Points at different things depending on how the function is invoked.

  • Invoking the function ‘this’ references the global namespace.

  • Inside a method of an object, ‘this’ references the object.

  • Can mutate the object by using ‘this’ keyword to access other properties and methods.

  • To protect against misrepresenting or assignment with ‘this’ keyword, use a variable to set the meaning of ‘this’ manually. Do this to utilise the scope chain over what the Js engine decides what the reference of ‘this’ is.

    • Var/let self = this; (inside object, set by reference).

    • This is a pattern in Js.

Arrays

  • Are a collection.

  • Array literal syntax: var arr = [1, 2, 3];

  • Js arrays can hold items of different types (unlike other languages due to dynamic vs static type checking).

Arguments and Spread

Arguments

  • Arguments contains a list of all the values of all the parameters that you pass to a function.

  • Args concept: the parameters you pass to a function, Js gives you a keyword which contain them all.

  • Args is the slightly older keyword, spread is the newer version

Spread

  • Can add extra arguments to a parameter without having to explicitly declare them by adding ‘(…other’)’ to end of parameter.

  • Function greet(f_name, l_name. …other) {…}

  • ‘…other’ allows multiple arguments that are wrapped in an an array called other.

Function Overloading

  • A function of the same name that has a different number of parameters.

  • Does not work in Js because functions are objects.

  • Can encapsulate default parameters values by having helper function call the main function.

Syntax Parser

  • reads your code character by character, line by line, determines if it has value and meaning.

Auto Semicolon Insertion

  • Semicolons are optional but it is very dangerous to do so.

  • Never do this as as syntax parser may change your code when compiling.

  • Js is very liberal with whitespace, use this to make code more readable and comment often.

Immediately Invoked Function Expressions (IIFE)s

  • Can invoke a function immediately after creating it by adding ‘()’ after the closing ‘}’.

  • Can return a value to variable that contains the function.

  • Can be stored as anonymous in global memory space.

  • When invoked a new execution context is created.

  • Can use this as a pattern to avoid crashes with global objects and set them intentionally. Entire Js file is wrapped in an function expression that return an object that can be referenced outside the file.

  • First word of a function has to be function.

  • Can trick parser to parse a function expression as a statement by wrapping function in ‘()’: ‘(function() {…})()’;

  • Parenthesis ‘()’ are an operator and can only be used with expressions.

Closures

  • Features of the Js language.

  • Give access to outer variables even after finishing execution.

  • Takes advantage of the scope chain.

  • Useful for functions that return a function (can invoke a function that was returned).

  • Even after execution context is finished variables in memory space still exist and can be referenced later by functions.

  • Thus going up the scope chain using the outer variable environment to find variables not in the current execution context.

  • Internal functions (invoked later) still have a reference to its parent functions latest execution context (outer variables) in memory space.

  • Js makes sure this scope chain is intact for closure to work.

  • The execution context has closed in its outer variables even after execution context is gone.

  • Can make interesting patterns utilising this feature (functional programming).

  • Closure gives access to the latest value of variable in memory space so not effective for accessing chaining values at different stages of the execution context. To get over this:

    • In ES6 use ‘let’ inside a loop or statement as it creates a new space in memory for each iteration value.

    • Invoke function immediately (function expression) to create a new execution context such that its environment variables are preserved in closure.

  • This is a fundamental aspect of advanced Js programming.

Garbage Collection

  • Clearing out used memory space.

Be careful when reading code functions, recognising function statements and expressions. A function must be invoked otherwise it is just a special object with a code property. Entire functions even anonymous functions are stored as plain text in memory space at creation phase.

Free Variables

  • Is a variable that is outside a function but you have access to it.

Function Factories

  • Using closure for this pattern.

  • Factory: a function that returns or make other things for me.

  • Passing a parameter into a function into a function and then returning the results of an inner function that contains more inner logic. - check this

  • Two functions may sit next to each other lexicaly but they have their own execution context/different memory space thus a different outer reference to a variable environment.

  • This allows function factories to take advantage of closure.

  • Take advantage of closure to set outer function parameter and return result (the function will always use the same default parameter value).

  • Any function called (no matter how many times) will get its own execution context and any function inside of it will point to that execution context.

  • Returning a function that has access to what the parameter variable was at that time of execution by pointing to that memory space. This lets you create functions from other functions.

Callback Functions

Callback

  • When a function is done executing, execute the other function in parameters (passing functions).

  • “I executed you, and you in turn execute this other function for me when your done”.

Callback Function

  • A function you give to another function to be run when the other function is finished.

  • The function you call (invoke) ‘calls back’ by calling the function you gave when it finishes.

  • Call function A and give it to B. When A is finished it calls function B when A is finished.

  • Invoke a function that will invoke the function you passed as a parameter.

Call(), Apply() and Bond()

  • The above methods control what the ‘this’ keyword variable binds too.

  • All functions (are objects) have access to the above methods mentioned.

  • These methods are used as an object and return a value, they are not invokable functions (dot syntax).

  • Pass to these functions whatever you want the ‘this’ variable to point too.

Bind()

  • Bind will return a new function, creating a new copy of the function object that invoked it.

  • Whatever object you pass will now be referenced as the new ‘this’ keyword.

Call()

  • Will invoke the function just like adding ‘()’ at the end of a function name.

  • However with .call(object) you can pass an object the ‘this’ keyword will then reference.

  • Can pass other parameters with call().

  • call() will not make a copy of the function like bind(), just invoke it.

Apply()

  • The apply() method works similar to the call however any extra parameters you pass must be inside an array.

  • Useful for mathematical equations.

Use these methods depending on your coding patterns and make interesting patterns to solve problems when controlling what ‘this’ keyword variable points too.

Function Borrowing

  • Two objects with similar properties can share access between each other object methods by using the above three methods mentioned.

  • Set the ‘this’ keyword for another function/object to borrow other methods.

  • Use ‘this’ to access and invoke methods as usual with dot syntax.

Function Currying

  • Can only be used with bind() as bind will not invoke functions, it treats parameters differently.

  • Bind() will permanently set the value of parameters passed in order into its own copy.

  • Parameters are binded in order of arguments.

  • After parameters are binded, extra parameters (not assigned to a variable) will be ignored.

  • Take a function, create a new function but with some preset parameters.

  • Creating a copy of a function but with some preset parameters.

  • Useful in mathematical situations.

Functional Programming

  • Js has more in common with functional programming languages than c# or java.

  • This is due to first class functions.

  • Think and create in terms of functions, a new approach to thinking and implementing.

  • Use first class functions to your advantage in order to segment code in even cleaner and tighter ways.

    • Not always possible in non-functional languages due to lack of first class functions limits possibilities.
  • Start thinking about how to give your functions, functions or return functions from functions.

  • Mutate data as high up in the chain as possible or not at all.

  • Underscore.js to help learn functional programming.

  • Lodash is another resource.

  • Code wrapped up as an immediately invoked function expression won’t clash with another namespace.

Section 5 OOP Js and prototypal Inheritance

Inheritance

  • One object gets access to the properties and methods of another objects.

  • Inheritance is different in Js compared to other languages.

Classical Inheritance

  • Verbose, the most popular way inheritance has been handled in c# and java.

  • Uses friend, protected, private and interface keywords.

Prototypal Inheritance

  • Simple, flexible, extensible and easy to understand.

  • Uses the prototype chain to add extra functionality to the base object.

Understanding The Prototype

  • All objects (including functions) in Js have a property called prototype.

  • Prototype is simply a reference to another object. It’s an object that stands on its own.

  • Prototype can link to other prototype properties. This is called the prototype chain.

  • Prototype chain: where we have access to a property or method against a sequence of objects that are connected by this prototype method.

  • Js will do the work of searching the chain for methods.

  • Objects can share all the same prototype because it’s just an object passed by reference.

  • All objects have a reference to another object and we call that its prototype, where it goes to look for properties and methods if not found on the original object.

  • ‘This’ and execution context will be created and reference what object originally called the method regardless of who’s method it was.

  • Warning: in the next version of Js (ES6) a new keyword called ‘extends’ will be available which sets the prototype. ‘Extends’ is used to combine and compose objects.

Section 6 Building Objects

  • Various ways to build objects in Js, especially when it comes to setting the prototype.

    • Object literal syntax, function constructors, ‘new’.
  • Utilising different features in Js to construct or build objects.

New

  • ‘New’ is actually an operator.

  • An empty object is created and then invokes the function.

  • ‘New’ changes what the ‘this’ variable points too.

  • ‘This’ points to that new empty object.

  • Properties and methods will now be added from the invoked function as long as the function does not override the Js engines default behaviour in not manually returning a value.

Function Constructor

  • A normal function that is used to build and construct objects.

  • Construct an object via a function, call a function that is specifically used to create a function.

  • Default values can be passed in parameters to set the values of the object.

  • The ‘this’ variable points to a new empty object and that object is returned from the function automatically.

  • ‘New’ makes the new empty object, function constructor adds the properties and methods to that new object.

Function Constructors and Prototype

  • When using function constructor the prototype is already set.

  • It has a special base prototype object when invoked by ‘new’.

  • Prototype property is used only by the ‘new’ operator. Sits and lives only when your using a function as a function constructor.

  • The prototype property on a function is not the prototype of the function. It’s the prototype of any objects created by the function when invoked as a function constructor.

  • Thus objects created by ‘new’ and function constructor their prototype will point to the prototype of the function constructor that created it.

  • Can now add features/methods to all objects created by the function constructor at any time due to the prototype chain.

  • This is useful because functionality is shared across multiple objects without duplicating code or taking memory space. Adding it to the base prototype object over each individual object having the same methods in their own memory space.

  • Function constructors in the prototype create objects where the prototype is already set thus allowing you to set methods and properties in one place giving all prototypes access.

  • Warning: not using the ‘new’ keyword will end up setting the variable to ‘undefined’ if no value is returned.

  • Good code practice to use camelcase function constructors.

  • Js also comes with built in function constructors that have prototype for boxed primitives and returns object with extra features.

  • Many libraries use this to add concepts, utilities and extra features to vanilla Js.

  • Don’t use built in function constructors on primitives, use literals or primitives themselfs or unexpected behaviour may occur unintentionally.

Array Properties

  • When iterating over an array, avoid for in loops as this will print all properties of the array including those down the prototype chain. Better to use the for loop and iterate.

  • This is because arrays are objects and items are added as properties.

Object.create and Pure Prototypal Inheritance

  • Function constructor was designed to mimic other languages that don’t have or implement prototypal inheritance.

  • Pure prototypical inheritance is completely empty, except properties and methods defined by user. Create an object and use that object as the prototype for other objects.

  • Newer browsers have this built in, Object.crate.

  • Object.create creates an empty object with its prototype pointing at whatever you passed into object.create.

  • The pattern to add new properties and methods is to simply override the existing ones on the new object.

  • That is pure prototypal inheritance.

  • If you want to create a new object simply define a new object that becomes the basis for all others.

  • Can add methods to both the base and newly created objects.

  • The main difference between pure prototypal and prototypal inheritance is that prototypal inheritance usually has an base object down the prototype chain with predefined features whereas in pure prototypal the empty object of a constructor is used as the base prototype for future objects.

Polyfill

  • The code that adds a feature which the engine may lack.

  • Used to extend the functionality of older incompatible browsers.

Note that methods inside an object need ‘this’ to find variables of the object when executed as objects don’t create execution contexts.

ES6 and Class

  • A new way to create classes and set the prototype.

  • Syntactically changes to literal object notation style to emulate languages like c# and java.

  • However in these languages a class is not an object, its just a template/definition until you hit that ‘new’ keyword.

  • Don’t confuse this new syntactactical sugar as anything else as an object in Js.

  • Uses prototypal inheritance and use ‘extends’ to set the prototype.

Syntactic Sugar

  • Different way to type something that doesn’t change how it works under the hood.

Section 7 Odds and Ends

Typeof

  • Is an operator to check the type of something.

  • Careful with arrays as this will return ‘object’ only.

Instanceof

  • If your dealing with chains, if it exists somewhere in the prototype chain.

Strict

  • “Use strict” as an optional flag to adhere to a stricker rule-set, set by the engine.

Section 8 Examining Famous Frameworks and Libraries

Learn advance patterns in Js by looking through the source code of popular frameworks and libraries.

Patterns

  • A function that calls a function constructor so you don’t have to type ‘new’ every time.

  • Have IIFE’s sitting inside each other much like jQuery does this with sizzle to parse in a whole other library.

  • Wrap your entire Js file as an IIFE to invoke the entire file into its own execution context in the global namespace.

  • Begin your Js file with a ‘;’ as a safety check to end any possible execution or parse happening before your code is executed.

Method Chaining

  • Calling one method after another and each method after the parent object.

  • So object.method1().method2() where both methods end up with a ‘this’ variable referencing the parent object that invoked the call.

  • ‘This’ will always point to the original object that made the call no matter how far the method is down the prototype chain.

Transpile

  • Convert the syntax of one programming language to another.

  • Languages can be transpiled to generate Js like typescript.