Javascript Flashcards

1
Q

Javascript Engine

A

A JavaScript engine is a computer program that you give JavaScript code to and it tells the computer how to execute it. Basically a translator for the computer between JavaScript and a language that the computer understands.

But what happens inside of the engine? Well, that depends on the engine.

There are many JavaScript Engines out there and typically they are created by web browser vendors. All engines are standardized by ECMA Script or ES.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Parser

A

Parsing is the process of analyzing the source code, checking it for errors, and breaking it up into parts.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

AST

A

The parser produces a data structure called the Abstract Syntax Tree or AST.

AST is a tree graph of the source code that does not show every detail of the original syntax, but contains structural or content-related details. Certain things are implicit in the tree and do not need to be shown, hence the title abstract.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Interpreter

A

An interpreter directly executes each line of code line by line, without requiring them to be compiled into a machine language program.

Interpreters can use different strategies to increase performance. They can parse the source code and execute it immediately, translate it into more efficient machine code, execute precompiled code made by a compiler, or some combination of these.

In the V8 engine, the interpreter outputs bytecode.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Compiler

A

The compiler works ahead of time to convert instructions into a machine-code or lower-level form so that they can be read and executed by a computer. It runs all of the code and tries to figure out what the code does and then compiles it down into another language that is easier for the computer to read.

Have you heard of Babel or TypeScript?

They are heavily used in the Javascript ecosystem and you should now have a good idea of what they are.

Babel is a Javascript compiler that takes your modern JS code and returns browser compatible JS (older JS code).

Typescript is a superset of Javascript that compiles down to Javascript. Both of these do exactly what compilers do. Take one language and convert into a different one!

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Explain how interpreter and profiler works together

A

In modern engines, the interpreter starts reading the code line by line while the profiler watches for frequently used code and flags then passes is to the compiler to be optimized.

In the end, the JavaScript engine takes the bytecode the interpreter outputs and mixes in the optimized code the compiler outputs and then gives that to the computer. This is called “Just in Time” or JIT Compiler.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Memoization

A

Memoization is a way to cache a return value of a function based on its parameters. This makes the function that takes a long time run much faster after one execution. If the parameter changes, it will still have to reevaluate the function.

Here are a few things you should avoid when writing your code if possible:

eval()
arguments
for in
with
delete
There are a few main reasons these should be avoided.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Hidden Classes

A

By setting these values in a different order than they were instantiated, we are making the compiler slower because of hidden classes.

Hidden classes are what the compiler uses under the hood to say that these 2 objects have the same properties.

If values are introduced in a different order than it was set up in, the compiler can get confused and think they don’t have a shared hidden class, they are 2 different things, and will slow down the computation.

Also, the reason the delete keyword shouldn’t be used is because it would change the hidden class.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Memory Heap

A

The JavaScript engine does a lot of work for us, but 2 of the biggest jobs are reading and executing it. We need a place to store and write our data and a place to keep track line by line of what’s executing.

That’s where the call stack and the memory heap come in.

The memory heap is a place to store and write information so that we can use our memory appropriately. It is a place to allocate, use, and remove memory as needed. Think of it as a storage room of boxes that are unordered.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Call stack

A

The call stack keeps track of where we are in the code, so we can run the program in order.

Things are placed into the call stack on top and removed as they are finished. It runs in a first in last out mode. Each call stack can point to a location inside the memory heap. In the above snippet the call stack looks like this.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Garbage Collection

A

JavaScript is a garbage collected language. If you allocate memory inside of a function, JavaScript will automatically remove it from the memory heap when the function is done being called.
However, that does not mean you can forget about memory leaks. No system is perfect, so it is important to always remember memory management.

JavaScript completes garbage collection with a mark and sweep method.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Synchronous

A

JavaScript is a single threaded language, meaning only one thing can be executed at a time. It only has one call stack and therefore it is a synchronous language.

So, what is the issue with being a single threaded language?

Lets’s start from the beginning. When you visit a web page, you run a browser to do so (Chrome, Firefox, Safari, Edge). Each browser has its own version of JavaScript Runtime with a set of Web API’s, methods that developers can access from the window object.

In a synchronous language, only one thing can be done at a time. Imagine an alert on the page, blocking the user from accessing any part of the page until the OK button is clicked. If everything in JavaScript that took a significant amount of time, blocked the browser, then we would have a pretty bad user experience.

This is where concurrency and the event loop come in.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Event Loop and Callback Queue

A

When you run some JavaScript code in a browser, the engine starts to parse the code. Each line is executed and popped on and off the call stack.

But, what about Web API’s?

Web API’s are not something JavaScript recognizes, so the parser knows to pass it off to the browser for it to handle. When the browser has finished running its method, it puts what is needed to be ran by JavaScript into the callback queue.

The callback queue cannot be ran until the call stack is completely empty. So, the event loop is constantly checking the call stack to see if it is empty so that it can add anything in the callback queue back into the call stack. And finally, once it is back in the call stack, it is ran and then popped off the stack.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Job Queue

A

The job queue or microtask queue came about with promises in ES6. With promises we needed another callback queue that would give higher priority to promise calls. The JavaScript engine is going to check the job queue before the callback queue.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

3 ways to promise

A

There are 3 ways you could want promises to resolve, parallel (all together), sequential (1 after another), or a race (doesn’t matter who wins).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Threads, Concurrency and Parallelism

A

Even though JavaScript is a single threaded language, there are worker threads that work in the background that don’t block the main thread.

Just like a browser creates a new thread when you open a new tab. The workers work through messages being sent, but don’t have access to the full program.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Web Workers

A

Web Workers are a simple means for web content to run scripts in background threads. The worker thread can perform tasks without interfering with the user interface. In addition, they can perform I/O using XMLHttpRequest (although the responseXML and channel attributes are always null) or fetch (with no such restrictions). Once created, a worker can send messages to the JavaScript code that created it by posting messages to an event handler specified by that code (and vice versa).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

Multithreading

A

Modern operating systems can run multiple programs at the same time. That’s why you can read this article in your browser (a program) while listening to music on your media player (another program). Each program is known as a process that is being executed. The operating system knows many software tricks to make a process run along with others, as well as taking advantage from the underlying hardware. Either way, the final outcome is that you sense all your programs to be running simultaneously.

Running processes in an operating system is not the only way to perform several operations at the same time. Each process is able to run simultaneous sub-tasks within itself, called threads. You can think of a thread as a slice of the process itself. Every process triggers at least one thread on startup, which is called the main thread. Then, according to the program/programmer’s needs, additional threads may be started or terminated. Multithreading is about running multiple threads within a single process.

For example, it is likely that your media player runs multiple threads: one for rendering the interface — this is usually the main thread, another one for playing the music and so on.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Execution Context

A

Code in JavaScript is always run inside a type of execution context. Execution context is simply the environment within which your code is ran.

There are 2 types of execution context in JavaScript, global or function.

There are 2 stages as well to each context, the creation and executing phase.

As the JavaScript engine starts to read your code, it creates something called the Global Execution Context.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Global Execution Context

A

Creation Phase

global object created
initializes this keyword to global
Executing Phase 3. Variable Environment created - memory space for var variables and functions created 4. initializes all variables to undefined (also known as hoisting) and places them with any functions into memory

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Function Execution Context

A

Only when a function is invoked, does a function execution context get created.

Creation Phase
argument object created with any arguments
initializes this keyword to point called or to the global object if not specified
Executing Phase
Variable Environment created - memory space for variable and functions created
initializes all variables to undefined and places them into memory with any new functions

The keyword arguments can be dangerous to use in your code as is. In ES6, a few methods were introduced that can help better use arguments.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

Arrow Functions

A

Some people think of arrow functions as just being syntactic sugar for a regular function, but arrow functions work a bit differently than a regular function.

They are a compact alternative to a regular function, but also without its own bindings to this, arguments, super, or new.target keywords. Arrow functions cannot be used as constructors and are not the best option for methods.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

Hoisting

A

Hoisting is the process of putting all variable and function declarations into memory during the compile phase.

In JavaScript, functions are fully hoisted, var variables are hoisted and initialized to undefined, and let and const variables are hoisted but not initialized a value.

Var variables are given a memory allocation and initialized a value of undefined until they are set to a value in line. So if a var variable is used in the code before it is initialized, then it will return undefined.

However, a function can be called from anywhere in the code base because it is fully hoisted. If let and const are used before they are declared, then they will throw a reference error because they have not yet been initialized.

Avoid hoisting when possible. It can cause memory leaks and hard to catch bugs in your code. Use let and const as your go to variables.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

Lexical Environment

A

A lexical environment is basically the scope or environment the engine is currently reading code in.

A new lexical environment is created when curly brackets {} are used, even nested brackets {{…}} create a new lexical environment.

The execution context tells the engine which lexical environment it is currently working in and the lexical scope determines the available variables.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

Scope Chain

A

Each environment context that is created has a link outside of its lexical environment called the scope chain. The scope chain gives us access to variables in the parent environment.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

Function and Block Scope

A

Most programming languages are block scoped, meaning every time you see a new { } (curly braces) is a new lexical environment.

However, JavaScript is function scoped, meaning it only creates a new local environment if it sees the keyword function on the global scope.

To give us access to block scope, in ES6 let and const were added to the language. Using these can prevent memory leaks, but there is still an argument to be made for using var.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
27
Q

Difference between var and let/const

A

Variable declarations with let and const work differently from the var variable declaration and I wanted to take a minute to explain.

When a lexical scope is entered and the execution context is created, the engine allocates memory for any var variable in that scope and initializes it to undefined.

The let and const variables only get initialized on the line they are executed on and only get allocated undefined if there is no assignment to the variable. Trying to access a let or const variable before it is declared or outside of its block without returning it will result in a Reference Error.

28
Q

IIFE

A

Immediately Invoked Function Expression or more simply IIFE is a JavaScript function that runs as soon as it is defined. Can also be referred to as a Self-Executing Anonymous Function.

Takeaway: Avoid polluting the global namespace or scope when possible.

29
Q

this

A

Here is this 4 ways:

new keyword binding - the new keyword changes the meaning of this to be the object that is being created.

implicit binding - “this” refers to the object that is calling it. It is implied, without doing anything its just how the language works.

explicit binding - using the “bind” keyword to change the meaning of “this”.

arrow functions as methods - “this” is lexically scoped, refers to it’s current surroundings and no further. However, if “this” is inside of a method’s function, it falls out of scope and belongs to the window object. To correct this, you can use a higher order function to return an arrow function that calls “this”.

30
Q

Lexical vs Dynamic Scope

A

A big gotcha for a lot of people working with *this is when a function is ran inside of another function. It gets a little confusing, but we can remember who called the function.

In JavaScript, that function defaults to the Window object. It happens because everything in JavaScript is lexically scoped except for the this keyword.

It doesn’t matter where it is written, it matters how it is called.

Changing anotherFunc() instead to an arrow function will fix this problem, as seen below. Arrow functions do not bind or set their own context for this.

If this is used in an arrow function, it is taken from the outside. Arrow functions also have no arguments created as functions do.

31
Q

Context vs Scope

A

Nifty Snippet: Context and Scope can sometimes be confusing terms in JavaScript.

Context refers to the value of the this keyword.

Scope refers to the current context and visibility of variables.

32
Q

Function Call, Apply, Bind

A

Call - Call is a method of an object that can substitute a different object than the one it is written on.
Apply - Apply is almost identical to call, except that instead of a comma separated list of arguments, it takes an array of arguments.
Bind - Unlike call and apply, bind does not run the method it is used on, but rather returns a new function that can then be called later.

33
Q

Currying

A

Currying is breaking down a function with multiple arguments into one or more functions that each accept a single argument.

34
Q

Objects in JavaScript

A

Objects are one of the broadest types in JavaScript, almost “everything” is an object. MDN Standard built-in objects

Booleans can be objects (if defined with the new keyword)
Numbers can be objects (if defined with the new keyword)
Strings can be objects (if defined with the new keyword)
Dates are always objects
Maths are always objects
Regular expressions are always objects
Arrays are always objects
Functions are always objects
Objects are always objects

35
Q

Primitive

A

Primitive - Primitive values are defined by being immutable, they cannot be altered. The variable assigned to a primitive type may be reassigned to a new value, but the original value can not be changed in the same way objects can be modified.

Primitives are passed by value, meaning their values are copied and then placed somewhere else in the memory. They are also compared by value. There are currently 7 primitive data types in JavaScript.

string
number
bigint
boolean
null
undefined
symbol

36
Q

Non Primitive

A

The only type that leaves us with is objects.

Objects are able to be mutated and their properties are passed by reference, meaning their properties are not stored separately in memory.

A new variable pointing to an object will not create a copy, but reference the original objects location in memory. Therefore, changing the 2nd object will also change the first.

There are two ways to get around this, Object.assign() or use the spread operator {…} to “spread” or expand the object into a new variable. By doing this, it will allow the new variable to be modified without changing the original. However, these only create a “shallow copy”.

37
Q

Shallow Copy

A

Shallow copy is a bit-wise copy of an object. A new object is created that has an exact copy of the values in the original object.

If any of the fields of the object are references to other objects, just the reference addresses are copied i.e., only the memory address is copied.

38
Q

Deep Copy

A

A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. A deep copy occurs when an object is copied along with the objects to which it refers.

39
Q

Type Coercion

A

Type coercion is the process of converting one type of value into another. There are 3 types of conversion in JavaScript.

to string
to boolean
to number

40
Q

Static vs Dynamic Typed

A

The major difference between static and dynamic typed languages is when the types of variables are checked.

Static typed languages (Java, C, C++, C#) are checked during the compile stage, so all types are known before run-time.

Dynamic languages (JavaScript, PHP, Python, Ruby, Perl) are checked on the fly, during the execution stage.

Also, after dividing the languages into dynamic and static, they are then divided again into strong and weak typed.

Weakly typed (JavaScript, PHP, C, C++) languages can make type coercions implicitly.

Strongly typed (Python, Ruby, C#, Java) do not allow conversions between unrelated types

41
Q

Function Constructor

A

Functions are objects in JavaScript, which is not true for other languages.

Because of that, they can be called multiple ways, but they can also be constructors. A function constructor creates a new object and returns it. Every JavaScript function, is actually a function object itself.

Almost everything in JavaScript can be created with a constructor. Even basic JavaScript types like numbers and strings can be created using a constructor.

42
Q

Prototypal Inheritance

A

Almost all objects in Javascript pass down properties through a prototype chain. We call this chain, prototypal inheritance. The child of the object “inherits” properties from its parent.

All objects in JavaScript are descended from the Object constructor unless deliberately created or altered to not do so. The objects inherit methods and properties from Object.prototype.

The prototype property also has an accessor property called __proto__ that creates a link between the current object and points to the object it was created from, the “prototype”.

43
Q

Prototype vs __proto__

A

Understanding the difference between __proto__ and prototype can be quite a confusing concept for JavaScript developers.

Every function in JavaScript automatically gets a prototype property when it is created that gives it the call, apply, and bind methods.

It doesn’t really do anything with regular functions, but in constructor functions the prototype property allows us to add our own methods to the objects we create.

The __proto__ property is what creates the link between prototype objects, the child inherits properties from the parent through the prototype chain.

Each time a new object is created in JavaScript, it uses the __proto__ getter function to use a built in constructor function based on what is being created.

This could be an Array, Boolean, Date, Number, Object, String, Function, or RegExp. Each one has their own separate properties and methods that they inherit from the constructor.

44
Q

Callable Object

A

Because functions are objects in JavaScript, this also gives them the ability to have properties added to them.

This creates a callable object, a special object that creates properties not available on normal objects.

Below is a visualization of how this works under the hood. This code can not be ran in the console, but it is a representation of how the object looks.

45
Q

Higher Order Functions

A

A Higher Order Function (HOF) is a function that either takes a function as an argument or returns another function. There are 3 kinds of functions in JavaScript.

function ()
function (a,b)
function hof() { return function () {} }
Instead of writing multiple functions that do the same thing, remember DRY (don’t repeat yourself). Imagine in the example below, if you separated each code out into individual functions how much more code you would be writing and how much code would be repeated.

46
Q

Closures

A

Closures allow a function to access variables from an enclosing scope or environment even after it leaves the scope in which it was declared.

In other words, a closure gives you access to its outer functions scope from the inner scope. The JavaScript engine will keep variables around inside functions that have a reference to them, instead of “sweeping” them away after they are popped off the call stack.

Two of the major reasons closures are so beneficial are memory efficiency and encapsulation.

47
Q

Encapsulation

A

Encapsulation means the restriction of direct access to some of an object’s components. It hides as much as possible of an object’s internal parts and only exposes the necessary parts to run. Why use encapsulation?

Security - Controlled access
Hide Implementation and Expose Behaviours
Loose Coupling - Modify the implementation at any time

48
Q

Object Oriented Programming

A

Object Oriented Programming, or OOP, is the idea that all code should be grouped into “boxes” (objects) to make your program easier to read and understand.

Keeping the data encapsulated helps to keep the program organized. Each object has a state that defines what it does and methods (functions on an object) that can use or modify the state.

Considering almost everything in JavaScript is an object, you would think this would be easy to do.

49
Q

Factory Functions

A

Factory functions return a new object every time they are ran.

50
Q

Constructor Functions

A

Using Object.create is true prototypal inheritance, the code is cleaner and easier to read. However, you will not see this being used in most programs.

Before Object.create came around, we had the ability to use constructor functions.

Constructor functions are exactly like the function constructor we talked about above. The number and string functions were constructed and invoked with the new keyword and they were capitalized.

The new keyword actually changes the meaning of this for the constructor function. Without new, this will point to the window object instead of the object that we just created.

It is best practice to capitalize constructor functions to help us identify them and know to use the new keyword. Properties added to a constructor function can only be done using the this keyword, regular variables do not get added to the object.

51
Q

Class

A

Confused yet? Prototype is a little weird and hard to read unless you really understand your prototypal inheritance.

No one really liked using the prototype way of adding methods, so ES6 JavaScript gave us the class keyword.

However, classes in JavaScript are not true classes, they are syntactic sugar. Under the hood, it is still using the old prototype method. They are in fact just “special functions” with one big difference; functions are hoisted and classes are not. You need to declare your class before it can be used in your codebase.

Classes also come with a new method, the constructor that creates and instantiates an object created with class. Classes are able to be extended upon using the extends keyword, allowing subclasses to be created.

If there is a constructor present in the extended class, the super keyword is needed to link the constructor to the base class. You can check if something is inherited from a class by using the keyword instanceof to compare the new object to the class.

52
Q

Private and Public Fields

A

Most class based languages have the ability to create either public or private fields within a class. Adding these to classes in JavaScript is still an experimental feature in development.

Support in browsers is limited, but can be implemented with systems like Babel.

Public declarations are set above the constructor and can be used within the class, but do not get added to a new instance.

The private declarations are set with the # sign in front of the variable and are only accessible within that class, they cannot be accessed or changed from outside.

53
Q

Functional Programming

A

Functional programming has the same goals in mind as object oriented programming, to keep your code understanable, easy to extend, easy to maintain, memory efficient, and DRY.

Instead of objects, it uses reusable functions to create and act on data.

Functional programming is based on a separation of concerns similar to object oriented programming. However, in functional programming, there is a complete separation between the data and the behaviors of a program.

There is also an idea that once something is created, it should not be changed, being immutable.

Unlike OOP, shared state is avoided as functional programming works on the idea of pure functions.

Functional programming just lays the foundation for creating reusable functions that can be moved around as needed.

For example, it is great in areas of industry and machine learning and it is even in some front end libraries like React and Redux. Redux really popularized functional programming for JavaScript developers.

54
Q

Pure Function

A

A pure function has no side effects to anything outside of it and given the same input will always output the same value. They do not change any data passed into them, but create new data to return without altering the original.

However, it is not possible to have 100% pure functions. At some point you need to interact with the dom or fetch an api.

Even console.log makes a function unpure because it uses the window object outside of the function. The fact is a program cannot exist without side effects.

So, the goal of functional programming is to minimize side effects by isolating them away from the data. Build lots of very small, reusable and predictable pure functions that do the following:

Complete 1 task per function.
Do not mutate state.
Do not share state.
Be predictable.
Be composable, one input and one output.
Be pure if possible.
Return something.

55
Q

Idempotence

A

Idempotence is another important piece of functional programming. It is the idea that given the same input to a function, you will always return the same output. The function could be used over and over again and nothing changes.
This is how you make your code predictable.

56
Q

Imperative vs Declarative

A

Declarative programming only tells the computer what to do, but not how to do things.

Humans are declarative by nature, but computers typically need more imperative type programming.

However, using higher level languages like JavaScript is actually being less declarative. This is important in function programming because we want to be more declarative to better understand our code and let the computer handle the dirty work of figuring out the best way to do something.

57
Q

Immutability

A

Immutability is simply not modifying the original data or state. Instead we should create copies of the state inside our functions and return a new version of the state.

You may be thinking that this could get really expensive, memory wise, to just copy code over and over. However, there is something called structural sharing that allows the data to only copy new information and points to the original state for any commonalities.

58
Q

Pipe and Compose

A

In JavaScript it is best for speed and efficiency to keep functions small and reusable.

Function composition is the idea that you lay out your functions like a factory assembly line. The actual functions pipe() and compose() don’t actually exist in JavaScript yet, but there are many libraries that use them.

You can however create your own versions of them. The compose() function reads the functions from right to left and the pipe() function will read from left to right.

59
Q

Composition vs Inheritance

A

Composition is what we just did with FP, creating small reusable functions to make code modular.

Inheritance is what we did with OOP, creating a class and extending it to subclasses that inherit the properties.

In OOP we create few operations on common data that is stateful with side effects.

In FP we create many operations on fixed data with pure functions that don’t mutate state. There is a big debate over which one is better and most people believe that composition is better.

Composition is probably a better tool to use when creating programs because it creates a more stable environment that is easier to change in the future.

60
Q

OOP Drawbacks

A

One of the drawbacks to inheritance is that it is based on the fact that it won’t change, we tell it what it is. We create a class and give it properties and methods that describe the class.

But say, down the road, we need to update that class and add more functionality. Adding a new method to the base class will create rippling effects through your entire program.

FP is more declarative, what to do not how, and OOP is more imperative, what and how to do something. This is the tight coupling problem, things having to depend on one another, which leads to the fragile base class problem, seemingly safe changes cause unforeseen repercussions.

It is the opposite of small reusable code. Changing one small thing in either of the class or subclasses could break the program.

Another problem is hierarchy where you may need to create a subclass that can only do 1 part of the class, but instead you get everything passed down to it

61
Q

Modules

A

Modules are pieces of code, grouped together, that can be combined together to create an expandable program that can get bigger as it needs to.

Good modules are self contained and grouped together with their own specific functionality allowing them to be moved or deleted without breaking the program.

Originally in JavaScript, we had the module pattern.

Before block scope came around, there was only global scope and function scope.

To create this idea of modules, a module scope was implemented just above the function scope. This allowed variables to be shared, by exporting and importing, between the functions without having to go through the global scope.

A function as a module is essentially just an immediately invoked function expression, IIFE.

62
Q

Module Issues

A

Even though modules help us to contain and organize code, there are still problems that can arise.

There can be naming conflicts if you don’t use const to declare the module. Also, there are dependency issues if scripts are placed in the wrong order, such as jQuery needing to be called before it can be used.

Because of these problems, people started developing libraries to solve them. Before ES6 we had 2 ways to implement modules in JavaScript CommonJS and AMD.

CommonJS - uses the keywords require and exports to interact with the module system.

Require is a function used to import from another module and exports is an object where functions get exported from. These are run synchronously where we wait on one module to load before another can start and this is not ideal for browsers.

However, this code may look familiar because NodeJS still uses this library. There are other packages such as Browserify and webpack that aid in bundling scripts with CommonJS to be used in the browsers.

Asynchronous Module Definition (AMD) - as in the name, AMD loads modules asynchronously.

This was great for browsers early on before packages that bundled code.

define([‘module1’, ‘module2’], function(module1, module2) {console.log(module1.setName());});

The define function takes an array of dependency modules that are loaded in a non-blocking manner in the background.

Once completed, the callback function is then executed. Packages came out like RequireJS thatimplemented the AMD endpoint and was the main way people used AMD modules.

63
Q

Error Handling

A

One of the most important things to learn in being a developer is how to solve errors. Learning to handle errors makes you a better programmer.

Writing your programs you have the ability to use the throw keyword to stop the program and handle an error by using a try/catch block that has an optional finally block or the .catch() method for asynchronous code.

Throwing a new error in asynchronous code gets what is called a silent fail if there is no catch block present.

In synchronous code, if there is no catch statement placed in the code, the runtime will create catch: onerror() and we see the built in JavaScript error message in red.

64
Q

Error Constructors

A

EvalError - an error with the global function eval().

InternalError - an error in the JavaScript engine is thrown. Usually when something is too large.

RangeError - an error when a numeric variable or parameter is outside of its valid range.

ReferenceError - an error that occurs when referencing something invalid. E.g. When a variable is used before it is declared.

SyntaxError - an error that occurs in parsing, the engine does not understand what is written.

TypeError - an error when a variable is not the correct type.

URIError - an error when encodeURI() or decodeURI() are passed invalid parameters.

Errors created using the new keyword come with 3 properties.

name - the name of the error.

message - the parameter given to the error.

stack - the stack trace or callback queue when the error occurred that also includes the line and character number where the error happened.

Because Error is a constructor function, we can use that to extend it and add to it. You don’t want to reveal parts of your program by allowing an error to give the stack trace and other information to possible bad actors. So, you can customize what you want your errors to reveal.

65
Q

Web Workers

A
  • Web worker is a separate JS thread that allows you to execute multiple threads of JS in parallel with each other
  • Offloads computationally expensive work so main thread doesn’t get bogged down
  • Main difference between main thread and worker thread is that it can’t perform DOM manipulations
66
Q

Service Workers

A
  • JS script that gets registered with browser
  • Stays registered with browser even when offline
  • Can load content even with no connection
  • Service worker jumps in the middle between browser and server and can intercept request
  • Can’t directly access the DOM
  • Programmable Network Proxy
  • Terminated when not being used
  • Make use of promises
  • Require HTTPS unless on localhost
    Common Cases
  • Caching assets and API calls
  • Push Notifications (Push & Notification API)
  • Background data sync/preload
  • Used in progressive web apps