Javascript Flashcards

1
Q

What is a Closure? How/why is it used?

A

A closure is an inner function that has access to the outer (enclosing) function’s variables—scope chain. The closure has three scope chains: it has access to its own scope (variables defined between its curly brackets), it has access to the outer function’s variables, and it has access to the global variables
Functions such as greet that use (ie. capture) such variables (ie. free variables) are called closures.

We can use closures to pass down arguments to helper functions without explicitly listing them as arguments.

function isPalindrome(string) {
  function reverse() {
    return string.split('').reverse().join('');
  }

return string === reverse();
}
Private State
Another major use of closures is to create private states. For example:

function Counter() {
  let count = 1;

return () => count++;
}

let counter = new Counter();
console.log(counter()); // => 1
console.log(counter()); // => 2
counter.count; // undefined
By closing over (or capturing) the count variable, each Counter function has private, mutable state that cannot be accessed externally.

Compare that implementation against this one:

function Counter () {
  this._count = 0;
}

Counter.prototype.fire = function () {
this._count += 1;
return this._count;
}

let counter = new Counter();
counter.fire(); // 1
counter.fire(); // 2
counter._count // 2
counter._count = 0 // 0 (this works);
One advantage of the closure way is that the count is truly private. In the first example, there is no way any method beside the closure itself can access the count state. In the second example, a foolish user might set counter._count inadvertently.
Free variables can be modified by closures. Consider this function:

function sum(nums) {
  let count = 0;
  function addNum(num) {
    count += num;
  }
  for (let i = 0; i < nums.length; i++){
    addNum(nums[i]);
  }

return count;
}

sum([1, 3, 5]) // => 9

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

What is the keyword ‘this’ in JavaScript? How is it used? How is it related to binding?

A

To access the object, a method can use the this keyword.

The value of this is the object “before dot”, the one used to call the method.

“this” is not bound
In JavaScript, “this” keyword behaves unlike most other programming languages. First, it can be used in any function.

The value of this is evaluated during the run-time. And it can be anything.

In JavaScript this is “free”, its value is evaluated at call-time and does not depend on where the method was declared, but rather on what’s the object “before the dot”.

The concept of run-time evaluated this has both pluses and minuses. On the one hand, a function can be reused for different objects. On the other hand, greater flexibility opens a place for mistakes.

First, know that all functions in JavaScript have properties, just as objects have properties. And when a function executes, it gets the ‘this’ property—a variable with the value of the object that invokes the function where ‘this’ is used.

The ‘this’ reference ALWAYS refers to (and holds the value of) an object—a singular object—and it is usually used inside a function or a method, although it can be used outside a function in the global scope. Note that when we use strict mode, this holds the value of undefined in global functions and in anonymous functions that are not bound to any object.

this is used inside a function (let’s say function A) and it contains the value of the object that invokes function A. We need this to access methods and properties of the object that invokes function A, especially since we don’t always know the name of the invoking object, and sometimes there is no name to use to refer to the invoking object. Indeed, this is really just a shortcut reference for the “antecedent object”—the invoking object.

Ruminate on this basic example illustrating the use of this in JavaScript

If you understand this one principle of JavaScript’s this, you will understand the “this” keyword with clarity: this is not assigned a value until an object invokes the function where this is defined. Let’s call the function where this is defined the “this Function.”

Even though it appears this refers to the object where it is defined, it is not until an object invokes the this Function that this is actually assigned a value. And the value it is assigned is based exclusively on the object that invokes the this Function. this has the value of the invoking object in most circumstances. However, there are a few scenarios where this does not have the value of the invoking object. I touch on those scenarios later.
As an object method
When a function is called as a method of an object, its this is set to the object the method is called on.

In arrow functions, this retains the value of the enclosing lexical context’s this. In global code, it will be set to the global object:

To pass the value of ‘this’ from one context to another, use call, or apply:

ECMAScript 5 introduced Function.prototype.bind. Calling f.bind(someObject) creates a new function with the same body and scope as f, but where this occurs in the original function, in the new function it is permanently bound to the first argument of bind, regardless of how the function is being used.

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

What is Callback Hell?

A

callback-hell is an obsolete frontend-programming problem that can be easily solved using recursion. the basic problem is that most i/o in frontend-programming (and backend if using nodejs) is asynchronous, and the naive way to try and make them run sequentially requires multiple-levels of nested async callbacks (this is a textbook example of a recursion problem).

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

In JavaScript, what is NaN and what is its type? How can you test if a value is equal to NaN?

A

NaN is a property of the global object.

The initial value of NaN is Not-A-Number — the same as the value of Number.NaN. In modern browsers, NaN is a non-configurable, non-writable property. Even when this is not the case, avoid overriding it.

It is rather rare to use NaN in a program. It is the returned value when Math functions fail (Math.sqrt(-1)) or when a function trying to parse a number fails (parseInt(“blabla”)).

Testing against NaN
NaN compares unequal (via ==, !=, ===, and !==) to any other value – including to another NaN value. Use Number.isNaN() or isNaN() to most clearly determine whether a value is NaN. Or perform a self-comparison: NaN, and only NaN, will compare unequal to itself.

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

What is hoisting in JavaScript? Give an example of how it might be used.

A

Hoisting is JavaScript’s default behavior of moving declarations to the top.

JavaScript Declarations are Hoisted
In JavaScript, a variable can be declared after it has been used.

In other words; a variable can be used before it has been declared.

Variables are partially hoisted. var declarations are hoisted but not its assignments.

let and const are not hoisted.

In JavaScript, declarations are hoisted by default. This means that variable and function declarations are put into memory at compile time. Therefore, it is actually possible, on execution, to call a declared function or variable before it is defined. For instance, the following will properly call the function sayHello.

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

What is scope?

A

Scope refers to the execution context. It defines the accessibility of variables and functions in the code.

Global Scope is the outermost scope. Variables declared outside a function are in the global scope and can be accessed in any other scope. In a browser, the window object is the global scope.

Local Scope is a scope nested inside another function scope. Variables declared in a local scope are accessible within this scope as well as in any inner scopes.

The scope of a method is the set of variables that are available for use within the method. The scope of a function includes:

the function’s arguments;
any local variables declared inside the function;
any variables that were already declared when the function was defined.
Consider this example:

function sayHelloNTimes(name, n) {
  function greet() {
    console.log( `Hi, ${name}!`);
  }
  for (let i = 0; i < n; i++) {
    greet();
  }
}

sayHelloNTimes(“Bob”, 3); // logs ‘Hi, Bob!’ x3
sayHelloNTimes(“Sally”, 6); // logs ‘Hi, Sally!’ x6

In the example above, the variable name is referenced by greet, even though it was never declared within greet. This is possible because a nested function’s scope includes variables declared in the scope where the function was nested.

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

What is the difference between apply, call, and bind

A

All of these three methods are used to attach this into function and the difference is in the function invocation.

.call() invokes the function immediately and requires you to pass in arguments as a list (one by one).

.apply() invokes the function immediately and allows you to pass in arguments as an array.

.call() and .apply() are mostly equivalent and are used to borrow a method from an object. Choosing which one to use depends on which one is easier to pass the arguments in.
the difference between call and apply:

Both can be called on functions, which they run in the context of the first argument. In call the subsequent arguments are passed in to the function as they are, while apply expects the second argument to be an array that it unpacks as arguments for the called function.

Bind is a bit different. It returns a new function. Call and Apply execute the current function immediately.

.bind() returns a new function, with a certain context and parameters. It is usually used when you want a function to be called later with a certain context.

Bind is great for a lot of things. We can use it to curry functions like in the above example. We can take a simple hello function and turn it into a helloJon or helloKelly. We can also use it for events like onClick where we don’t know when they’ll be fired but we know what context we want them to have.
ind is a method you can call on JS functions. Other methods defined on Function objects live in Function.prototype.

bind works just like the closure we made, in which cat#ageOneYear is called method style on the cat object. cat.ageOneYear.bind(cat) returns a closure that will still be called function-style, but which calls cat.ageOneYear method-style inside of it.

Note that you can bind functions to any scope, not just this:

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

What is global scope?

A

JavaScript has global scope, represented by the ‘window’ object in the browser and the ‘global’ object in Node.js. Adding attributes to these objects makes them available throughout a program.

function theBest() {
  window.realMVP = 'you';
}

theBest(); // initializes realMVP on the global scope

window.realMVP; // ‘you’

function whoDaBest() {
  return realMVP; // 'you'
}

whoDaBest(); // ‘you’
While useful on occasion, global variables are usually best avoided, as they give too much code access to their values, increasing the likelihood of bugs.

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

What is “Use Strict”

A

A common mistake new JS developers commit is to unintentionally create global variables. This happens if you declare a variable without the var, let, or const keywords anywhere in your code, and can lead to strange behavior. Consider:

window.local; // undefined

function subroutine(){
  local = 'oops';
}

subroutine();

window.local // ‘oops’;
Thankfully, modern JS runtimes support strict mode, which prohibits variable declaration without var, let, or const.

“use strict”;

window.local; // undefined

function subRoutine(){
  local = 'oops';
}

subRoutine(); // ReferenceError: ‘local’ is not defined
Note: “use strict” does not work in the Node CLI or the Dev Tools console.

Some of its benefits are:

Makes debugging easier — Code errors that would otherwise have been ignored will now generate errors, such as assigning to non-writable global or property.
Prevents accidental global variables — Assigning a value to an undeclared variable will now throw an error.
Prevents invalid use of delete — Attempts to delete variables, functions and undeletable properties will now throw an error.
Prevents duplicate property names or parameter values — Duplicated named property in an object or argument in a function will now throw an error. (This is no longer the case in ES6)
Makes eval() safer — Variables and functions declared inside an eval() statement are not created in the surrounding scope.
“Secures” JavaScript eliminating this coercion — Referencing a this value of null or undefined is not coerced to the global object. This means that in browsers it’s no longer possible to reference the window object using this inside a function.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is the difference between initializing and declaring a variable?

A

Declaring a variable reserves a name and some space in memory for a variable of the specified type, but doesn’t give it a value. Initializing gives the variable a value. Depending on how you’re going to use the variable, you can declare it without initializing it and then initialize it later, or declare and initialize at the same time. For examp

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

Describle Prototype and __proto__ in JS.

A

Every function has the “prototype” property even if we don’t supply it.

The default “prototype” is an object with the only property constructor that points back to the function itself.

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

undefined vs null

A

undefined means a variable has been declared but has not yet been assigned a value. On the other hand, null is an assignment value. It can be assigned to a variable as a representation of no value. Also, undefined and null are two distinct types: undefined is a type itself (undefined) while null is an object.

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

discuss Prototype and inheritance

A

Prototype is one of the most confusing concepts in JavaScript and one of the reason for that is because there are two different contexts in which the word prototype is used.

Prototype relationship
Each object has a prototype object, from which it inherits all of its prototype’s properties.
.__proto__ is a non-standard mechanism (available in ES6) for retrieving the prototype of an object (). It points to the object’s “parent” — the object’s prototype.
All normal objects also inherit a .constructor property that points to the constructor of the object. Whenever an object is created from a constructor function, the .__proto__ property links that object to the .prototype property of the constructor function used to create it.
(
) Object.getPrototypeOf()is the standard ES5 function for retrieving the prototype of an object.
Prototype property
Every function has a .prototype property.
It references to an object used to attach properties that will be inherited by objects further down the prototype chain. This object contains, by default, a .constructor property that points to the original constructor function.
Every object created with a constructor function inherits a constructor property that points back to that function.

Like class Dog inheriting from class Animal

We need to make sure the the Dog proto points to the Animal prototype and not the Object prototype..

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

What is console.table?

A

If the data type is that of an object, .table will log out the results in table form.

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

How would we use JS to scrape data from a site?

A

1) Get DOM elements off page (we have to be on the page to do so)
2) Use document.querySelector(‘.thing’)
3) Then it depends on whats next
- if its with links, do category.querySelectorAll(‘a’) &laquo_space;tag. We will get a NodeList (not array)

4) take the category query (using Array.from OR […category.querySelector(‘a)

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

Deconstruct arrays

A

if there are, say, split values, if we declare a variable encased in []’s with multiple variables, we can extract the individual values, rather place the values directly into the respective variables in the array. When the enclosed variables are returned or logged individually

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

how to use reduce to tally n objects

A

create a counter obj within reduce. the oj is the acc and the item is el and the starting value is {}

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

What is propertyName?

A

The propertyName property returns the name of the CSS property associated with the transition, when a transitionevent occurs.

This property is read-only.

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

What variable declaration does a non-declared variable take by default?

A

Var

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

Discuss difference between const let an var

A

Const cannot be reassigned, but the properties can be changed (in an object or its array values).

Neither let or const can be hoisted.

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

Closures: What is IIFE and what is a good example of when/how to use it?

A

An immediately-invoked function expression (or IIFE, pronounced “iffy”) is a JavaScript programming language idiom which produces a lexical scope using JavaScript’s function scoping.

An IIFE is a function expression that is called immediately after you define it. It is usually used when you want to create a new variable scope.

The (surrounding parenthesis) prevents from treating it as a function declaration.

The final parenthesis() are executing the function expression.

On IIFE you are calling the function exactly when you are defining it.

Incorrect: 
const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log(`The value ${arr[i]} is at index: ${i}`);
  }, (i+1) * 1000);
}

“The value undefined is at index: 4”. This happens because each function executed within the loop will be executed after the whole loop has completed, referencing to the last value stored in i, which was 4.

This problem can be solved by using IIFE, which creates a unique scope for each iteration and storing each value within its scope.
const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  (function(j) {
    setTimeout(function() {
      console.log(`The value ${arr[j]} is at index: ${j}`);
    }, j * 1000);
  })(i)
}

Or

Another solution would be declaring the i variable with let, which creates the same result.
const arr = [10, 12, 15, 21];
for (let i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log(`The value ${arr[i]} is at index: ${i}`);
  }, (i) * 1000);
}
var result = [];
for (var i=0; i < 5; i++) {
  result.push( function() { return i } );
}
console.log( result[1]() ); // 5
console.log( result[3]() ); // 5
result = [];
for (var i=0; i < 5; i++) {
  (function () {
    var j = i; // copy current value of i
    result.push( function() { return j } );
  })();
}
console.log( result[1]() ); // 1
console.log( result[3]() ); // 3

Using IIFE:

Enables you to attach private data to a function.
Creates fresh environments.
Avoids polluting the global namespace.

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

Describe Context

A

Context is often confused as the same thing as Scope. To clear things up, lets keep the following in mind:
Context is most often determined by how a function is invoked. It always refers to the value of this in a particular part of your code.
Scope refers to the visibility of variables.

23
Q

What does the ‘new’ Keyword do?

A

The new keyword invokes a function in a special way. Functions invoked using the new keyword are called constructor functions.

So what does the new keyword actually do?

Creates a new object.
Sets the object’s prototype to be the prototype of the constructor function.
Executes the constructor function with this as the newly created object.
Returns the created object. If the constructor returns an object, this object is returned.

24
Q

What is prototype chain?

A

The prototype chain is a series of links between objects that reference one another.

When looking for a property in an object, JavaScript engine will first try to access that property on the object itself.

If it is not found, the JavaScript engine will look for that property on the object it inherited its properties from — the object’s prototype.

The engine will traverse up the chain looking for that property and return the first one it finds.

The last object in the chain is the built-in Object.prototype, which has null as its prototype. Once the engine reaches this object, it returns undefined.

25
Q

Event Loop

A

In computer science, the event loop, message dispatcher, message loop, message pump, or run loop is a programming construct that waits for and dispatches events or messages in a program.

In JS:

26
Q

What is Javascript?

A

A single-threaded, non-blocking asynchronous concurrent language.
It has a call stack, event loop, a callback queue, and other apis.

27
Q

What is V8?

A

an open-source JavaScript engine developed by The Chromium Project for Google Chrome and Chromium web browsers.[5] The project’s creator is Lars Bak.[6] The first version of the V8 engine was released at the same time as the first version of Chrome: September 2, 2008. It has also been used in Couchbase, MongoDB and Node.js that are used server-side.

V8 compiles JavaScript directly to native machine code before executing it, instead of more traditional techniques such as interpreting bytecode or compiling the whole program to machine code and executing it from a filesystem. The compiled code is additionally optimized (and re-optimized) dynamically at runtime, based on heuristics of the code’s execution profile. Optimization techniques used include inlining, elision of expensive runtime properties, and inline caching.

V8 can compile to x86, ARM or MIPS instruction set architectures in both their 32- and 64-bit editions; as well, it has been ported to PowerPC[7] and IBM s390[8][9] for use in servers.[3][10]

Oddly enough certain asynchronous functions like settimeout are missing from v8 source.

28
Q

What is the call stack?

A

One thread == one call stack
JS can do one thing at a time.

It records where in the program we are.

We step into a function, we put something on top of the stack.

We return from a function, we pop off of the stack.
the idea is that it will execute in order.

We get call stack errors when a function calls itself over and over and over without a basecase to stop it.

29
Q

What is blocking? (What happens when things are slow?) . Whats a solution?

A

When we make a network request, we just have to wait until its done.
This is a problem because we are using browsers. Browser will get stuck waiting until each previous request clears.

Solution: Asynchronous callbacks!

30
Q

What is concurrency and the event loop all about?

A

JS can only do one thing at a time. However, the browser has threads/APIs that we can make calls to.
Example of browser API:
setTimeout
ajax request

Once a program is complete, it will be popped off the stack.

WebAPIs cant just modify code.

They will push the callback on the task queue.

The eventloop’s job is to look at the stack and look at the queue. If the stack is empty, it will push the queued item onto the stack. this item will run on the stack then ultimately be dequeued.

I think the idea isthat we will be able to issue many commands at once when interacting with a website.

The clicks wont process immediately, they will be pushed onto the queue. I think this is what’s happening when we are waiting for sites to load.

syncronously, the stack clears after every action.
asyncronously, the stack sends the stacked itsems to the web apis which enqueue them one after another, waiting for their time to execute.

31
Q

Difference between == and ===

A

. ===
It is widely spread that == checks for equality and === checks for equality and type. Well, that is a misconception.

In fact, == checks for equality with coercion and === checks for equality without coercion — strict equality.

32
Q

Classes in JS

A

JavaScript classes, introduced in ECMAScript 2015, are primarily syntactical sugar over JavaScript’s existing prototype-based inheritance. The class syntax does not introduce a new object-oriented inheritance model to JavaScript.

An important difference between function declarations and class declarations is that function declarations are hoisted and class declarations are not. You first need to declare your class and then access it, otherwise code will throw a reference error.

A class expression is another way to define a class. Class expressions can be named or unnamed. The name given to a named class expression is local to the class’s body. (it can be retrieved through the class’s (not an instance’s) .name property, though)

The bodies of class declarations and class expressions are executed in strict mode i.e. constructor, static and prototype methods, getter and setter functions are executed in strict mode.

The constructor method is a special method for creating and initializing an object created with a class. There can only be one special method with the name “constructor” in a class. A SyntaxError will be thrown if the class contains more than one occurrence of a constructor method.

A constructor can use the super keyword to call the constructor of the super class.

The static keyword defines a static method for a class. Static methods are called without instantiating their class and cannot be called through a class instance. Static methods are often used to create utility functions for an application. Kind of like private methods?

The extends keyword is used in class declarations or class expressions to create a class as a child of another class.

If there is a constructor present in sub-class, it needs to first call super() before using “this”.

Note that classes cannot extend regular (non-constructible) objects. If you want to inherit from a regular object, you can instead use Object.setPrototypeOf():

var Animal = {
  speak() {
    console.log(this.name + ' makes a noise.');
  }
};
class Dog {
  constructor(name) {
    this.name = name;
  }
}
// If you do not do this you will get a TypeError when you invoke speak
Object.setPrototypeOf(Dog.prototype, Animal);
var d = new Dog('Mitzie');
d.speak(); // Mitzie makes a noise.
33
Q

What is a prototype?

A

An object that contains properties/methods that point back to constructor.

34
Q

What is a constructor?

A

A normal function (which is a special object of its own). At the highest level, it is a function called Object.

new Object( ) . or { } . <=== this has a prototype with its own built in methods.

35
Q

What is __proto__?

A

An object within an instance of a contructor function that points to the prototype (and its properties) of the parent.

Its just a pointer to the parent.

When we make an instance of a function, it sets the proto to the prototype of the parent function. If we want proper inheritance, we have to either use Object.create(every functions parent anyway) or a Surrogate. Surrogate.prototype = Animal.prototype
Dog.prototype = new Surrogate (points to the Animal’s prototype)

Make sure we end with Dog.prototype.constructor = Dog

36
Q

What is bubbling?

A

The bubbling principle is simple.

When an event happens on an element, it first runs the handlers on it, then on its parent, then all the way up on other ancestors.

Stopping bubbling
A bubbling event goes from the target element straight up. Normally it goes upwards till , and then to document object, and some events even reach window, calling all handlers on the path.

But any handler may decide that the event has been fully processed and stop the bubbling.

The method for it is event.stopPropagation().

37
Q

What is event.target?

A

event.target
A handler on a parent element can always get the details about where it actually happened.

The most deeply nested element that caused the event is called a target element, accessible as event.target.

Note the differences from this (=event.currentTarget):

event.target – is the “target” element that initiated the event, it doesn’t change through the bubbling process.
this – is the “current” element, the one that has a currently running handler on it.
For instance, if we have a single handler form.onclick, then it can “catch” all clicks inside the form. No matter where the click happened, it bubbles up to and runs the handler.

In form.onclick handler:

this (=event.currentTarget) is the element, because the handler runs on it.
event.target is the concrete element inside the form that actually was clicked.

When an event happens – the most nested element where it happens gets labeled as the “target element” (event.target).
Then the event first moves from the document root down the event.target, calling handlers assigned with addEventListener(…., true) on the way.
Then the event moves from event.target up to the root, calling handlers assigned using on and addEventListener without the 3rd argument or with the 3rd argument false.
Each handler can access event object properties:

event. target – the deepest element that originated the event.
event. currentTarget (=this) – the current element that handles the event (the one that has the handler on it)
event. eventPhase – the current phase (capturing=1, bubbling=3).

38
Q

What is capturing?

A

Capturing
There’s another phase of event processing called “capturing”. It is rarely used in real code, but sometimes can be useful.

The standard DOM Events describes 3 phases of event propagation:

Capturing phase – the event goes down to the element.
Target phase – the event reached the target element.
Bubbling phase – the event bubbles up from the element.

If one puts capturing and bubbling handlers on the target element, the capture handler triggers last in the capturing phase and the bubble handler triggers first in the bubbling phase.

39
Q

ES5 vs ES6

A

ECMAScript 6 (ES6) features can be divided into features that are pure syntactic sugar (like: class), features that enhance JavaScript (like import) and features that fix some of JavaScript’s “bad” parts (like the let keyword).

  1. Block Scope
    ES5 only had “function-level scope” (i.e. you wrap code in functions to create scope) and caused a lot of issues. ES6 provides “block”-level scoping(i.e curly-braces to scope) when we use “let” or “const” instead of “var”.

It prevents hoisting.

Prevent Duplicate Variable Declaration
ES6 doesn’t allow duplicate declaration of variables when we declare them using “let” or “const” in the same scope. This is very helpful in avoiding duplicate function expressions coming from different libraries (like the “add” function expression below).

Eliminates The Need For IIFE
In ES5, in cases like below, we had to use Immediately Invoked Function Expression (IIFE) to ensure we don’t not pollute or overwrite the global scope. In ES6, we can just use curly braces ({}) and use const or let to get the same effect.

babel — A Tool to convert ES6 to ES5
We need to ultimately run ES6 in a regular browser. Babel is the most popular tool used to convert ES6 to ES5. It has various interfaces like a CLI, Node-module and also an online converter. I use the node module for my apps and use the online version to quickly see the differences.

n ES5, if you had a function inside a loop (like for(var i = 0; i < 3; i++) {…}), and if that function tried to access the looping variable “i”, we’d be in trouble because of hoisting. In ES6, if you use “let”, you can use functions without any issue.

  1. Lexical “this” (via Arrow Functions)
    In ES5, “this” can vary based on “where” it is called and even “how” it is called and has caused all sorts of pains for JS developers. ES6 eliminates this major issue by “lexical” this.

The Solution in ES6
Simply use the fat-arrow function => and you get the lexical “this” automatically.

  1. Dealing With “arguments”
    In ES5, “arguments” acts like an Array (i.e. we can loop over it), but is not an Array. So, all the Array functions like sort, slice and so on are not available.

In ES6, we can use a new feature called “Rest” parameters. It’s represented with 3 dots and a name like …args. Rest parameters is an Array and so we can use all the Array functions.

  1. Classes
    Conceptually, there is no such thing as a “Class”(i.e. blueprint) in JS like it is in other OO languages like Java. But people for a long time have treated the “function” (aka “function constructors”) that creates Objects when we use the “new” keyword as Classes.

And since JS doesn’t support the “Classes” and just simulates it via “prototypes”, it’s syntax has been very confusing for both existing JS developers and new comers who wants to use it in a traditional OO fashion. This is especially true for things like: creating subclasses, calling functions in parent class and so on.

ES6 brings a new syntax that’s common in various programming languages and makes the whole thing simple. Below picture shows a side-by-side comparison of ES5 and ES6 classes.

5. Strict Mode
Strict Mode(“use strict”) helps identify common issues (or “bad” parts) and also helps with “securing” JavaScript. In ES5, the Strict Mode is optional but in ES6, it’s needed for many ES6 features. So most people and tools like babel automatically add “use strict” at the top of the file putting the whole JS code in strict mode and forcing us to write better JavaScript.
40
Q

What is lexical this?

A

Lexical “this” a feature that forces the variable “this” to always point to the object where it is physically located within.

41
Q

What is REST syntax

A
Rest syntax (parameters)
Rest syntax looks exactly like spread syntax, but is used for destructuring arrays and objects. In a way, rest syntax is the opposite of spread syntax: spread 'expands' an array into its elements, while rest collects multiple elements and 'condenses' them into a single element. See rest parameters.
42
Q

JS Error Handling: Try…Catch

A

The try..catch construct has two main blocks: try, and then catch:

try {

// code…

} catch (err) {

// error handling

}

First, the code in try {…} is executed.
If there were no errors, then catch(err) is ignored: the execution reaches the end of try and then jumps over catch.
If an error occurs, then try execution is stopped, and the control flows to the beginning of catch(err). The err variable (can use any name for it) contains an error object with details about what’s happened.

For try..catch to work, the code must be runnable. In other words, it should be valid JavaScript.

It won’t work if the code is syntactically wrong, for instance it has unmatched curly braces:

try..catch works synchronously
If an exception happens in “scheduled” code, like in setTimeout, then try..catch won’t catch it:

To catch an exception inside a scheduled function, try..catch must be inside that function:

43
Q

JS Error Handling: Error Object

A

When an error occurs, JavaScript generates an object containing the details about it. The object is then passed as an argument to catch:

try {
  // ...
} catch(err) { //
44
Q

Error Handling: Throwing our own errors

A

“Throw” operator
The throw operator generates an error.

The syntax is:

throw
Technically, we can use anything as an error object. That may be even a primitive, like a number or a string, but it’s better to use objects, preferrably with name and message properties (to stay somewhat compatible with built-in errors).

JavaScript has many built-in constructors for standard errors: Error, SyntaxError, ReferenceError, TypeError and others. We can use them to create error objects as well.

Their syntax is:

let error = new Error(message);
// or
let error = new SyntaxError(message);
let error = new ReferenceError(message);
// ...
For built-in errors (not for any objects, just for errors), the name property is exactly the name of the constructor. And message is taken from the argument.

For instance:

let error = new Error(“Things happen o_O”);

alert(error.name); // Error
alert(error.message); // Things happen o_O
Let’s see what kind of error JSON.parse generates:

try {
  JSON.parse("{ bad json o_O }");
} catch(e) {
  alert(e.name); // SyntaxError
  alert(e.message); // Unexpected token o in JSON at position 0
}
As we can see, that’s a SyntaxError.
45
Q

JS Error Handling: What is rethrowing?

A

Catch should only process errors that it knows and “rethrow” all others.

The “rethrowing” technique can be explained in more detail as:

Catch gets all errors.
In catch(err) {…} block we analyze the error object err.
If we don’t know how to handle it, then we do throw err.
In the code below, we use rethrowing so that catch only handles SyntaxError:

let json = '{ "age": 30 }'; // incomplete data
try {

let user = JSON.parse(json);

  if (!user.name) {
    throw new SyntaxError("Incomplete data: no name");
  }

blabla(); // unexpected error

alert( user.name );

} catch(e) {

  if (e.name == "SyntaxError") {
    alert( "JSON Error: " + e.message );
  } else {
    throw e; // rethrow (*)
  }

}
The error throwing on line (*) from inside catch block “falls out” of try..catch and can be either caught by an outer try..catch construct (if it exists), or it kills the script.

So the catch block actually handles only errors that it knows how to deal with and “skips” all others.

46
Q

JS Error Handling: try…catch…finally

A

Wait, that’s not all.

The try..catch construct may have one more code clause: finally.

If it exists, it runs in all cases:

after try, if there were no errors,
after catch, if there were errors.
The extended syntax looks like this:

          try {
   ... try to execute the code ...
} catch(e) {
   ... handle errors ...
} finally {
   ... execute always ...
}
Try running this code:
 try {
  alert( 'try' );
  if (confirm('Make an error?')) BAD_CODE();
} catch (e) {
  alert( 'catch' );
} finally {
  alert( 'finally' );
}
The code has two ways of execution:

If you answer “Yes” to “Make an error?”, then try -> catch -> finally.
If you say “No”, then try -> finally.
The finally clause is often used when we start doing something before try..catch and want to finalize it in any case of outcome.

For instance, we want to measure the time that a Fibonacci numbers function fib(n) takes. Naturally, we can start measuring before it runs and finish afterwards. But what if there’s an error during the function call? In particular, the implementation of fib(n) in the code below returns an error for negative or non-integer numbers.

The finally clause is a great place to finish the measurements no matter what.

finally and return
The finally clause works for any exit from try..catch. That includes an explicit return.

In the example below, there’s a return in try. In this case, finally is executed just before the control returns to the outer code.

function func() {

try {
return 1;

  } catch (e) {
    /* ... */
  } finally {
    alert( 'finally' );
  }
}

alert( func() ); // first works alert from finally, and then this one

47
Q

Js Error Handling: Global Catch;

A

Let’s imagine we’ve got a fatal error outside of try..catch, and the script died. Like a programming error or something else terrible.

Is there a way to react on such occurrences? We may want to log the error, show something to the user (normally he doesn’t see error messages) etc.

There is none in the specification, but environments usually provide it, because it’s really useful. For instance, Node.JS has process.on(‘uncaughtException’) for that. And in the browser we can assign a function to special window.onerror property. It will run in case of an uncaught error.

The syntax:

window.onerror = function(message, url, line, col, error) {
  // ...
};
message
Error message.
url
URL of the script where error happened.
line, col
Line and column numbers where error happened.
error
Error object.
For instance:

window.onerror = function(message, url, line, col, error) {
alert(${message}\n At ${line}:${col} of ${url});
};

  function readData() {
    badFunc(); // Whoops, something went wrong!
  }

readData();

The role of the global handler window.onerror is usually not to recover the script execution – that’s probably impossible in case of programming errors, but to send the error message to developers.

There are also web-services that provide error-logging for such cases, like https://errorception.com or http://www.muscula.com.

They work like this:

We register at the service and get a piece of JS (or a script URL) from them to insert on pages.
That JS script has a custom window.onerror function.
When an error occurs, it sends a network request about it to the service.
We can log in to the service web interface and see errors.

48
Q

JS Error Handling: In General

A

The try..catch construct allows to handle runtime errors. It literally allows to try running the code and catch errors that may occur in it.

The syntax is:

try {
  // run this code
} catch(err) {
  // if an error happened, then jump here
  // err is the error object
} finally {
  // do in any case after try/catch
}
There may be no catch section or no finally, so try..catch and try..finally are also valid.

Error objects have following properties:

message – the human-readable error message.
name – the string with error name (error constructor name).
stack (non-standard) – the stack at the moment of error creation.
We can also generate our own errors using the throw operator. Technically, the argument of throw can be anything, but usually it’s an error object inheriting from the built-in Error class. More on extending errors in the next chapter.

Rethrowing is a basic pattern of error handling: a catch block usually expects and knows how to handle the particular error type, so it should rethrow errors it doesn’t know.

Even if we don’t have try..catch, most environments allow to setup a “global” error handler to catch errors that “fall out”. In-browser that’s window.onerror.

49
Q

Js: Custom Errors

A

3 main points:
- We can inherit from Error and other built-in error classes normally, just need to take care of name property and don’t forget to call super.

  • Most of the time, we should use instanceof to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from the 3rd-party library and there’s no easy way to get the class. Then name property can be used for such checks.
  • Wrapping exceptions is a widespread technique when a function handles low-level exceptions and makes a higher-level object to report about the errors. Low-level exceptions sometimes become properties of that object like err.cause in the examples above, but that’s not strictly required.
50
Q

JS: Custom Errors - Extending Error

A
class Error {
  constructor(message) {
    this.message = message;
    this.name = "Error"; // (different names for different built-in error classes)
    this.stack = ; // non-standard, but most environments support it
  }
}
class ValidationError extends Error {
  constructor(message) {
    super(message); // (1)
    this.name = "ValidationError"; // (2)
  }
}
function test() {
  throw new ValidationError("Whoops!");
}
try {
  test();
} catch(err) {
  alert(err.message); // Whoops!
  alert(err.name); // ValidationError
  alert(err.stack); // a list of nested calls with line numbers for each
}
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = "ValidationError";
  }
}
// Usage
function readUser(json) {
  let user = JSON.parse(json);
  if (!user.age) {
    throw new ValidationError("No field: age");
  }
  if (!user.name) {
    throw new ValidationError("No field: name");
  }

return user;
}

// Working example with try..catch

try {
let user = readUser(‘{ “age”: 25 }’);
} catch (err) {
if (err instanceof ValidationError) {
alert(“Invalid data: “ + err.message); // Invalid data: No field: name
} else if (err instanceof SyntaxError) { // (*)
alert(“JSON Syntax Error: “ + err.message);
} else {
throw err; // unknown error, rethrow it (**)
}
}

51
Q

JS: Custom Errors - Further Inheritance

A
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = "ValidationError";
  }
}
class PropertyRequiredError extends ValidationError {
  constructor(property) {
    super("No property: " + property);
    this.name = "PropertyRequiredError";
    this.property = property;
  }
}
// Usage
function readUser(json) {
  let user = JSON.parse(json);
  if (!user.age) {
    throw new PropertyRequiredError("age");
  }
  if (!user.name) {
    throw new PropertyRequiredError("name");
  }

return user;
}

// Working example with try..catch

try {
let user = readUser(‘{ “age”: 25 }’);
} catch (err) {
if (err instanceof ValidationError) {
alert(“Invalid data: “ + err.message); // Invalid data: No property: name
alert(err.name); // PropertyRequiredError
alert(err.property); // name
} else if (err instanceof SyntaxError) {
alert(“JSON Syntax Error: “ + err.message);
} else {
throw err; // unknown error, rethrow it
}
}
class MyError extends Error {
constructor(message) {
super(message);
this.name = this.constructor.name;
}
}

class ValidationError extends MyError { }

class PropertyRequiredError extends ValidationError {
  constructor(property) {
    super("No property: " + property);
    this.property = property;
  }
}
// name is correct
alert( new PropertyRequiredError("field").name ); // PropertyRequiredError
52
Q

JS: Custom Errors - Wrapping Exceptions

A
lass ReadError extends Error {
  constructor(message, cause) {
    super(message);
    this.cause = cause;
    this.name = 'ReadError';
  }
}
class ValidationError extends Error { /*...*/ }
class PropertyRequiredError extends ValidationError { /* ... */ }
function validateUser(user) {
  if (!user.age) {
    throw new PropertyRequiredError("age");
  }
  if (!user.name) {
    throw new PropertyRequiredError("name");
  }
}
function readUser(json) {
  let user;
  try {
    user = JSON.parse(json);
  } catch (err) {
    if (err instanceof SyntaxError) {
      throw new ReadError("Syntax Error", err);
    } else {
      throw err;
    }
  }
  try {
    validateUser(user);
  } catch (err) {
    if (err instanceof ValidationError) {
      throw new ReadError("Validation Error", err);
    } else {
      throw err;
    }
  }

}

try {
  readUser('{bad json}');
} catch (e) {
  if (e instanceof ReadError) {
    alert(e);
    // Original error: SyntaxError: Unexpected token b in JSON at position 1
    alert("Original error: " + e.cause);
  } else {
    throw e;
  }
}
53
Q

What is a promise?

A

The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.

A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action’s eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.

A Promise is in one of these states:

pending: initial state, neither fulfilled nor rejected.
fulfilled: meaning that the operation completed successfully.
rejected: meaning that the operation failed.
A pending promise can either be fulfilled with a value, or rejected with a reason (error). When either of these options happens, the associated handlers queued up by a promise’s then method are called. (If the promise has already been fulfilled or rejected when a corresponding handler is attached, the handler will be called, so there is no race condition between an asynchronous operation completing and its handlerspro being attached.)

As the Promise.prototype.then() and Promise.prototype.catch() methods return promises, they can be chained.