.Net fundamentals

async c#

Will your code be "writing for something"? (such as database read/write

Then I/O Bound (use async and await without task.Run)

Expensive computation ?

Then CPU bound (use task.run)

finally-block (used to release resources) ex: close any streams or files that were opened in the try block

"await" doesn't block the thread caller (MAIN UI).

just marks to the compiler that the process could-take time (will block rest of method though)

Exception handling

catch-blocks (Most specific to least specific)

using ( ) creates finally block Under the hood

Objects

Object is Instance of a class that resides in memory

Instance = accessible from the Object

static = accessible from teh class

public class() {}

reference types set to Null

sets chars to empty

bools to false

ints to 0

strings = null

this = references the current object

STACK and HEAP

Everything is Value Type (stored on STACK) or Reference Type (stored on HEAP)

value types (Bytes, int, float, struct) have short lifetime. SOON as "out-of-scope" kicked off STACK by Run-Time

reference types = objects

Each Data-type in c# is a class or structure

Structures are value types

Classes are referenced types

Execution Context

Stores Variables

Variable Object Context

Global Execution Object: Code that isn't in any function. Window object in Browser

Any function call is a new execution context

Context is always the value of the this keyword which is a reference to the object that “owns” the currently executing code.

“this” is a keyword used in JavaScript that has a special meaning depending on the context it’s being used

Function-stack (call stack) follows a LIFO(Last in First Out) order.

Stacking will not happen no matter how many function calls are made in the same Lexical Environment and scope. They all just push and pop within the same environment.

Execution Context basic

Global Scope is created internally by JavaScript as var window = Window() (rough equivalent) behind the veil.

Global Scope acts as the first automatically created Execution Context roughly at the time when the browser opens a URL

Variables defined with var, let, or const are created within Variable Environment. This is why they are not automatically tied to the window object nor bound to this object

Scoping Pie Chart Scoping Pie Chart 2 Scoping Pie Chart 3

A new Execution Context is caused by a function call. This new Execution Context is then placed on top of Execution Stack (or The Call Stack).

A new Execution Context can also be created when an object is instantiated — but its only because object instantiation is a constructor function call.

    Hoisting

  • variables in JS are available BEFORE the execution actually starts.
  • don't have to declare functions() before calling them
  • Variables are set to undefined in the creation phase

ONLY way to create a new scope in JS is to create new functions...

lexical scoping - a function() inside another function gets access to the scope of the outer functions().

'this' inside a function POINTS TO THE GLOBAL Object (even inner functions)

    CLOSURES

  • don't have to manually create them
  • Inner-function has access to the variables and parameters of its outer-function, even after outer function has returned (think backpack)
  • Closures Backpack Analogy
  • Function A() declares variable X and returns function B(). Function B() CAN access variable X because of closures
  • In module pattern, public methods can access private functions and variables because a CLOSURE was created

    WHEN program calls a function:

  • JS creates a new execution context (local)...
  • ...That local context will have its own set of variables...
  • ...New Execution Context thrown onto the execution-stack.
Execution Context Detailed

Event Loop JS

The job of the Event loop is to look into the call stack and determine if the call stack is empty or not. If the call stack is empty, it looks into the message queue to see if there’s any pending callback waiting to be executed.

    Event Loop simplied:

  1. 3 Parts: Execution Stack, WEB APIs, Message Que
  2. As functions() called they go onto the Execution Stack...As they return they Pop() off the stack
  3. Asyncs (timeOuts() etc...), DOM Events (event listeners etc...) go with their Timers to the Web API and get knocked off Execution Stack so that other functions can execute
  4. Once time finishes on the Asyncs...their callbackFunction() get sent to MessageQue
  5. CallBackFunctions() sit in MessageQue until ExeuctionStack() is empty (then Event Loop pushes it onto the stack)
Execution Stack basic Event Loop in JS example Event Loop in JS example Event Loop in JS example Event Loop in JS example Event Loop in JS example

The main JS runtime is single-threaded...so two functions can't run at the same time.

The runtime contains an Event Queue which stores a list of messages to be processed.

There are no race conditions, no deadlocks. However, the code in the Event Queue needs to run fast...otherwise the Browser will become unresponsive and will ask to kill the task.

Event Loop Steps:

As functions() called they go onto the Execution Stack...As they return they Pop() off the stack (think STACK data structure).

    Async(such as setTimeout())

  • Go with their Timers to the Web Api section...That call gets knocked off the stack(execution stack)
  • Rest of Execution Stack() can now execute
  • Once time finishes...callbackFunction() gets sent to the Message Que:
  • Message Que calls that function ONCE all other functions() are off the Execution Stack()

    Web API

  • setTimeout() - sits in there until Time Ends...then callBack funcion() moved to the MessageQue
  • DOM events - such as EventListener() sits in here
  • XMLHttpRequest()

EVENT loop - monitors the Execution-stack so that once it's empty it can push the next Message Que function() onto it

DOM Evetns processed when the Execution Stack is empty

ES6 introduced the concept of job queue/micro-task queue which is used by Promises in JavaScript. The difference between the message queue and the job queue is that the job queue has a higher priority than the message queue, which means that promise jobs inside the job queue/ micro-task queue will be executed before the callbacks inside the message queue.

While the event loop is executing the tasks in the micro-task queue and in that time if another promise is resolved, it will be added to the end of the same micro-task queue, and it will be executed before the callbacks inside the message queue no matter for how much time the callback is waiting to be executed.

async Event-Loop JS

Async event-loop with Promises

async Event Loop example with Promise

Document Object Model

Event Loop in JS example

'this' inside a function() points to the Global object (the DOM usually)

EVENT Bubbling: Events bubble up inside the DOM-tree

Event Bubbling JS Event Loop in JS example
Event Delegation

Attach it to the parent element and wait for it (catch it)

Use cases:

...Have an element w/ lots of child elements we're interested in

...When we want an Event handler attached to an element that is not yet in the DOM when our page is loaded

Event Loop in JS example

    document methods:

  • document.querySelector('id').textContent = variable
  • document.querySelector('.id').style.display = "none" (set the image or text to blank)
  • document.querySelector('.className').value (grab user input)

Hoisting and Scoping

In a nutshell, scoping and hoisting effect how the code we write will deal with our declarations (such as var, let, const and function).

Global Scope is created internally by JavaScript as var window = Window() (rough equivalent) behind the veil.

Global Scope acts as the first automatically created Execution Context roughly at the time when the browser opens a URL

Variables defined with var, let, or const are created within Variable Environment. This is why they are not automatically tied to the window object nor bound to this object

Scoping Pie Chart Scoping Pie Chart 2 Scoping Pie Chart 3

    var

  • When using var to declare your variables, the parent function where you declare your vars inside is your only de facto scope delimiter. This way, the parent function creates and holds the scope for all the local variables declared within itself. This is Local Scope...
  • ...As opposed to Global Scope, when the variables are declared outside your function. They are accessible by everyone and everywhere. They are omnipresent like the air we breathe, or like the window object in the browser.
  • Hence, other code blocks as conditionals and loops (such as if, for, while, switch and try) do not delimit scope, unlike most other languages. Then, any var inside these blocks will be scoped within their parent function which contains that block...
  • ...Not only that, but during runtime, every var declaration that is found inside such code blocks gets moved to the beginning of its parent function (its scope). This is the definition of Hoisting.
var and its scoping

    let and const

  • ES2015 introduced let and const which are variables that do respect the block scope. This means they are safe to be declared within a block and won’t leak outside, as the following example:
let and const scoping

Keep in mind that we have created one pair of i and parameter variables for each iteration of the for loop. Compare this to before when we just had one single i and parameter being rewritten each time. This matters a little bit for memory consumption.

Finally, since we also created the setTimeout callback function within the same scope, they will co-live with the protected values of i and parameter. Block scope will remain preserved even after stepSum finished executing

    functions

  • declaring a function is different than declaring a var and assigning a function to it...
  • function name() will get hoisted to top of scope
  • IF use var nameFunction = function() and call it before you declared...will get an error
  • The difference here is that when a function is hoisted, its body is also hoisted. Compared to when a var is hoisted, only its declaration gets hoisted but not its assignment.
 more let and const scoping

Inside the forEach block, the function total is hoisted, so when the `total += parameter;` line runs, it uses the function total, not the total variable defined outside of the forEach block. This means the let total varaible is unaffected by the forach block, so when the total is returned, it’s value is still 0, the same as it was at creation.

Functions

Functions are objects, can be assigned to variables, stored in objects or arrays, passed as an argument to other functions, and returned from functions.

A JS function is an object becaues its prototype is an object, and so it inherits methods from the protype

main JS runtime is single-threaded....so two functions can't run at same time.

Functions (except for arrow functions) have two pseudo-parameters: this and arguments

    3 ways to define a function:

  • 1) Function Declaration (aka Function Statement)
  • 2) Function Expression (aka Function Literal)
  • 3) Arrow Function

Functions can be used before declaration since function declarations are moved, or "hoisted", to the top of their scope. (variables set to undefined in creation phase)

Closures are not formed with anonymous functions

Function A() declares variable X and returns Function B()....Function B() CAN access variable X because of closures

in module pattern, public methods can access private functions and variables because a CLOSURE was created.

    WHEN program calls a function...

  • JS creates a new execution context (local)
  • That local context will have its own set of variables
  • New Execution Context thrown onto the execution-stack

    WHEN function ends...

  • Local execution context pops off the stack
  • Return value sent back to the calling context. Global or if no return statement..."undefined" returned
  • Local context destroyed

functions this
Callback Functions

function to be executed AFTER another has finished

Why need CallBack Functions?...

...JS is Event - Driven language (will keep executing while listening for other events)...

...Callbacks are a way to make certain code doesn't execute until other code has already finished execution.

Can use callBack functions() to defer activities into future to make our CODE NonBlocking.

Pass a reference to a function as an argument... you do this the function you’re passing as an argument is called a callback function and the function you’re passing the callback function to is called a higher order function.

Callback Function basic More Callback Function basic Complex CallBack Function example

first Class Functions = passing functions as parameters to other functions

'this' inside a function() points to the Global object (the DOM usually)

Methods are functions that are stored in objects. Functions are independent. In order for a function to know on which object to work on this is used. this represents the function's context

The value of this depends on how the function was invoked, not where the function was defined.

There is no point to use this when a function is invoked with the function form: doSomething(). In this case this is undefined or is the window object, depending if the strict mode of JS is enabled or not.

When a function is invoked with the method form: theObject.doSomething(), this represents the object.

When a function is used as a constructor: new Constructor(), this represents the newly created object.

When a function sits in the global scope, then the value of ‘this’ is the Window object. Think of it as the test function being a method on the context in which it sits (the window object).

However, if a function is executed in strict mode, ‘this’ will return undefined because strict mode does not allow default binding.

The value of this can be set with apply() or call(): doSomething.apply(theObject). In this case this is the object sent as the first parameter to the method.

Arrow Function

sugar syntax for creating an anonymous function expression.

let doSomething = () => {};

Arrow Functions don't have their own this and arguments

Share the surrounding this keyword...

An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. These function expressions are best suited for non-method functions, and they cannot be used as constructors

...lexical this variable (use arrow functions to preserve value of this)

Every async function() always returns a Promise

Destructuring = returning multiple values from a function()

Immediately Invoked Function Expression is only called ONCE (IIFE)

    Private Functions

  • Exposed functions can be accessed from the outer scope
  • Other code cannot overwrite private functions and variables
  • An exposed public interface is sometimes called an API
how this works with arrow functions

loops

break

when break is used inside two nested for loops, control comes out of the inner loop only.

async JS

consuming promise example chaining promises example fetch api example of promise chaining via fetch API promise example with some destructuring Race promises example

modules JS

ES Module syntax ES module syntax 2 ES module syntax 3 ES module syntax 4 ES module syntax 5 CORS considerations with modules

Sets

JS Set methods JS Set methods 2 JS Set methods 3 JS Set methods 4 JS Set methods 5 weak Set