Back to Course Overview

Hand-in-Period-1

Hand-in

Explain and Reflect

Explain the differences between Java and JavaScript.

You should include both topics related to the fact that Java is a compiled language and JavaScript a scripted language, and general differences in language features.

  Java JavaScript
Compiled vs Interpreted Java is a compiled programming language.
Java is compiled into bytecode and run on a virtual machine
JavaScript is an interpreted scripting language.
JavaScript can be interpreted directly by a browser in the syntax it is written.
Static vs Dynamic Type Checking Java uses static type checking, where the type of a variable is checked at compile-time. The programmer must specify the type (integer, double, string, etc.) of any variable they create. JavaScript, like most scripting languages, uses dynamic typing, where type safety is verified at runtime. It is not required for a programmer to specify the type of any variable they create.
Concurrency Java makes use of multiple threads to perform tasks in parallel. JavaScript, particularly as it exists as Node.js in server-side applications, handles concurrency on one main thread of execution via a queue system called the event loop, and a forking system called Node Clustering.
Class Based vs Prototype Based Java follows class based inheritance—a top down, hierarchical, class-based relationship whereby properties are defined in a class and inherited by an instance of that class. In JavaScript, inheritance is prototypal—all objects can inherit directly from other objects. Hierarchy is accomplished in JavaScript by assigning an object as a prototype with a constructor function.

Explain the two strategies for improving JavaScript: ES6 (es2015) + ES7, versus Typescript.

What does it require to use these technologies: In our backend with Node and in (many different) browsers

ES6 (es2015) + ES7

ES6 and ES7 is newer implementations of JavaScript, which implements some new features, like async/await. Our browsers don’t understand these new implementations, which means that in order for the browser to understand our code, it has to be transpiled into ES5, which all modern browser understand. The most used transpilers for JavaScript is Babel or Webpack.

TypeScript

TypeScript is a strict syntactical superset of JavaScript, and adds optional static typing to the language. As TypeScript is a superset of JavaScript, existing JavaScript programs are also valid TypeScript programs. TypeScript may be used to develop JavaScript applications for both client-side and server-side (Node.js) execution. TypeScript supports definition files that can contain type information of existing JavaScript libraries, this enables other programs to use the values defined in the files as if they were statically typed TypeScript entities. The TypeScript compiler, named tsc, is written in TypeScript. As a result, it can be compiled into regular JavaScript and can then be executed in any JavaScript engine (e.g. a browser). The compiler package comes bundled with a script host that can execute the compiler. It is also available as a Node.js package that uses Node.js as a host.

Explain generally about node.js, when it “makes sense” and npm, and how it “fits” into the node echo system.

Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications.
It uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

Node vs Java - similarities

npm (short for Node.js package manager) is a package manager for the JavaScript programming language. It is the default package manager for the JavaScript runtime environment Node.js. It consists of a command line client, also called npm, and an online database of public and paid-for private packages, called the npm registry. The registry is accessed via the client, and the available packages can be browsed and searched via the npm website.

Many modules is designed to do one thing, the Node echo system encourages to use such modules instead of one module that does everything

Explain about the Event Loop in Node.js

Node.js is a single-threaded application, but it can support concurrency via the concept of event and callbacks. Every API of Node.js is asynchronous and being single-threaded, they use async function calls to maintain concurrency. Node uses observer pattern. Node thread keeps an event loop and whenever a task gets completed, it fires the corresponding event which signals the event-listener function to execute.

Node.js uses events heavily and it is also one of the reasons why Node.js is pretty fast compared to other similar technologies. As soon as Node starts its server, it simply initiates its variables, declares functions and then simply waits for the event to occur.

In an event-driven application, there is generally a main loop that listens for events, and then triggers a callback function when one of those events is detected.

Although events look quite similar to callbacks, the difference lies in the fact that callback functions are called when an asynchronous function returns its result, whereas event handling works on the observer pattern. The functions that listen to events act as Observers. Whenever an event gets fired, its listener function starts executing.

Explain (some) of the purposes with the tools Babel and WebPack, using examples from the exercises

Babel

Babel is a JavaScript transpiler that converts edge JavaScript into plain old ES5 JavaScript that can run in any browser (even the old ones).

It makes available all the syntactical sugar that was added to JavaScript with the new ES6 specification, including classes, fat arrows and multiline strings.

WebPack

ES6 modules allow the JavaScript developer to break their code up into manageable chunks, but the consequence of this is that those chunks have to be served up to the requesting browser, potentially adding dozens of additional HTTP requests back to the server — something we really ought to be looking to avoid. This is where webpack comes in.

Webpack is a module bundler. Its primary purpose is to process your application by tracking down all its dependencies, then package them all up into one or more bundles that can be run in the browser.

Explain the purpose of “use strict” and Linters, exemplified with ESLint

The “use strict” directive was new in ECMAScript version 5. It is not a statement, but a literal expression, ignored by earlier versions of JavaScript. The purpose of “use strict” is to indicate that the code should be executed in “strict mode”. With strict mode, you can not, for example, use undeclared variables.

“Use strict” and linters are tools to protect us form ourselves. They warn us when our code contains a syntax error, and tells us if the variable we defined or assigned a value isn’t being used. This improves the quality of our code, and may save time we would have use on debuging.

Explain using sufficient code examples the following features in JavaScript

Variable/function-Hoisting

Hoisting means lifting up. In JavaScript a var declaration is hoisted to the top of its scope.

console.log(x)
var x = 10

is equivalent to

var x
console.log(x)
x = 10

output

undefined

The declaration is hoisted not the assignment.
Function declarations is also hoisted to the top of its scope

sayHi()
function sayHi(){
    console.log('Hi')
}

is equivalent to

function sayHi(){
    console.log('Hi')
}
sayHi()

output

Hi

this in JavaScript and how it differs from what we know from Java/.net.

this in JavaScript typically refers to the function it is called in, while in Java it refers to the class.

function Car(make,model) {
    this.make = make;
    this.model = model;
    this.show = function(){setTimeout(function(){ //This function gets it's own "this"
        console.log(this.make + ", " + this.model);
    },0)};
}
var car = new Car("Volvo","V70");
car.show();

output

undefined, undefined

if a function is defined as a arrow function it does not get its own this

function Car(make,model) {
    this.make = make;
    this.model = model;
    this.show = function(){setTimeout(()=>{ //This function doesn't gets it's own "this"
        console.log(this.make + ", " + this.model);
    },0)};
}
var car = new Car("Volvo","V70");
car.show();

output

Volvo, V70

Function Closures and the JavaScript Module Pattern

Closures

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.
The inner function has access not only to the outer function’s variables, but also to the outer function’s parameters. Note that the inner function cannot call the outer function’s arguments object, however, even though it can call the outer function’s parameters directly.

function showName (firstName, lastName) {
    var nameIntro = "Your name is ";
        // this inner function has access to the outer function's variables, including the parameter
    function makeFullName () {
        return nameIntro + firstName + " " + lastName; 
    }
    return makeFullName ();
}
showName ("Michael", "Jackson");

output

Your name is Michael Jackson

Module Pattern

The Module pattern was originally defined as a way to provide both private and public encapsulation for classes in conventional software engineering.
In JavaScript, the Module pattern is used to further emulate the concept of classes in such a way that we’re able to include both public/private methods and variables inside a single object, thus shielding particular parts from the global scope. What this results in is a reduction in the likelihood of our function names conflicting with other functions defined in additional scripts on the page.

var modularpattern = (function() {
    // your module code goes here
    var sum = 0 ;

    return {
        add:function() {
            sum = sum + 1;
            return sum;
        },
        reset:function() {
            return sum = 0;    
        }  
    }   
}());
console.log(modularpattern.add())
console.log(modularpattern.add())
console.log(modularpattern.reset())

output

1
2
0

Immediately-Invoked Function Expressions (IIFE)

Immediately-Invoked Functions are functions that are invoked when the script reaches that part of the code.

(function iife(){
    console.log('I am an Immediately-Invoked Function Expression')
})()

!(() => {
 console.log('I too am an Immediately-Invoked Function Expression')
})()

output

I am an Immediately-Invoked Function Expression
I too am an Immediately-Invoked Function Expression

JavaScripts Prototype

const names = ['Lars', 'Jan', 'Peter', 'Bo', 'Frederik']
names.prototype.myMap = function(callback){
    let arr = []
    for(let i = 0; i < this.length; i++){
            arr.push(callback(this[i]))
    }
    return arr
}
const names = ['Lars', 'Jan', 'Peter', 'Bo', 'Frederik']
names.prototype.myFilter = function(callback){
    let arr = []
    for(let i = 0; i < this.length; i++){
        if(callback(this[i])){
            arr.push(this[i])
        }
    }
    return arr
}

User-defined Callback Functions (writing your own functions that take a callback)

function myFilter(callback){
    let arr = []
    for(let i = 0; i < this.length; i++){
        if(callback(this[i])){
            arr.push(this[i])
        }
    }
    return arr
}
function myMap(callback){
    let arr = []
    for(let i = 0; i < this.length; i++){
            arr.push(callback(this[i]))
    }
    return arr
}

Explain the methods map, filter and reduce

Array.prototype.map(): The map() method creates a new array with the results of calling a provided function on every element in the calling array.

const numbers = [2, 3, 4, 5]
const mappedNumbers = numbers.map((e) => e * 2)
console.log(mappedNumbers);

output

[4, 6, 8, 10]

Array.prototype.filter(): The filter() method creates a new array with all elements that pass the test implemented by the provided function.

const names = ['Lars', 'Jan', 'Peter', 'Bo', 'Frederik']
const filteredNames = names.filter(name => name.length <= 3)
console.log(filteredNames)

output

["Jan", "Bo"]

Array.prototype.reduce(): The reduce() method executes a reducer function (that you provide) on each member of the array resulting in a single output value.

The reducer function takes four arguments:

  1. Accumulator (acc)
  2. Current Value (cur)
  3. Current Index (idx)
  4. Source Array (src)

Your reducer function’s returned value is assigned to the accumulator, whose value is remembered across each iteration throughout the array and ultimately becomes the final, single resulting value.

const numbers = [2, 3, 4, 5]
const reducer = (acc, cur, idx, src) => accumulator + currentValue)
console.log(numbers.reduce(reducer);

output

14

Provide examples of user-defined reusable modules implemented in Node.js

module.exports.makeCounter = function(){
    let privateCounter = 0
    function changeBy(val){
        privateCounter += val
    }
    return {
        increment: function(){
            changeBy(1)
        },
        decrement: function(){
            changeBy(-1)
        },
        value: function(){
            return privateCounter
        }
    }
}

ES6,7,8… and TypeScript

Provide examples and explain the es2015 features: let, arrow functions, this, rest parameters, de-structuring assignments, maps/sets etc.

let and const

With ES6 it is now possible to declare a variable that behaves more like we expect them to behave. While a var declaration is hoisted to the top of its scope a let or a const declaration is not hoisted and behaves like we know variable declarations from Java. The difference between a let and a const is that the let can be assigned a new value and the const can’t.

arrow functions

// Defining a function
function addNumbers(a, b) {
    return a + b;
}
// Using anonymous function
var addNumbers = function(a, b) {
    return a + b;
}
// using Arrow Functions with return statement
var addNumbers = (a, b) => {
    return a + b;
}
// Using Arrow Functions without return statements and without curly braces
var addNumbers = (a, b) => a + b; // implicit return statement

this

thisis a unique keyword whose value changes depending on how it is called. When it is called outside a function, this refers to the Window object in the browser.

console.log(this) // Window

When this is called in a function, this is set to the global object.

function hello () {
    console.log(this)
}
hello() // Window

When this is called in an object method, this would be the object itself.

let o = {
    sayThis: function() {
        console.log(this)
    }
}

o.sayThis() // o

When the function is called as a constructor, this refers to the newly constructed object.

function Person (age) {
    this.age = age
}
let greg = new Person(22)
let thomas = new Person(24)
console.log(greg) // this.age = 22
console.log(thomas) // this.age = 24

When used in an event listener, this is set to the element that fired the event.

let button = document.querySelector('button')
button.addEventListener('click', function() {
    console.log(this) // button
})

In arrow functions, this never gets bound to a new value, no matter how the function is called. this will always be the same this value as its surrounding code.

rest parameters

function f (x, y, ...rest) {
    return (x + y) * rest.length
}
f(1, 2, "hello", true, 7) === 9

destructuring

Array Matching

var list = [ 1, 2, 3 ]
var [ a, , b ] = list // a === 1, b === 3
[ b, a ] = [ a, b ] // b === 1, a === 3

Object Matching, Shorthand Notation

var { op, lhs, rhs } = getASTNode()

Object and Array Matching, Default values

var obj = { a: 1 }
var list = [ 1 ]
var { a, b = 2 } = obj // a === 1, b === 2
var [ x, y = 2 ] = list // x === 1, y === 2

sets

let s = new Set()
s.add("hello").add("goodbye").add("hello")
s.size === 2 // no duplicate entries
s.has("hello") === true
for (let key of s.values()) // insertion order
    console.log(key)

maps

let m = new Map()
let s = Symbol()
m.set("hello", 42)
m.set(s, 34)
m.get(s) === 34
m.size === 2
for (let [ key, val ] of m.entries())
    console.log(key + " = " + val)

Explain and demonstrate how es2015 supports modules (import and export) similar to what is offered by NodeJS.

//  lib/math.js
export function sum (x, y) { return x + y }
export var pi = 3.141593

//  someApp.js
import * as math from "lib/math"
console.log("2π = " + math.sum(math.pi, math.pi))

//  otherApp.js
import { sum, pi } from "lib/math"
console.log("2π = " + sum(pi, pi))

Provide an example of ES6 inheritance and reflect over the differences between Inheritance in Java and in ES6.

class Shape {
    color;
    constructor(color) {
        this.color = color
    }
}

class square extends Shape {
    length;
    constructor(color, length) {
        super(color)
        this.length = length
    }
}

JavaScript Object inheritance is Prototype based. ES6 classes are just syntactic sugar to make it look similar to OOP languages like Java. Behind the scene, no Class based inheritance but Prototype based inheritance.

Provide examples with es-next, running in a browser, using Babel and Webpack

Examples can be found here

Provide a number of examples to demonstrate the benefits of using TypeScript, including, types, interfaces, classes and generics

Examples can be found here

Explain the ECMAScript Proposal Process for how new features are added to the language (the TC39 Process)

Each proposal for an ECMAScript feature goes through the following maturity stages, starting with stage 0. The progression from one stage to the next one must be approved by TC39.

Stage 0: strawman

What is it? A free-form way of submitting ideas for evolving ECMAScript. Submissions must come either from a TC39 member or a non-member who has registered as a TC39 contributor.

What’s required? The document must be reviewed at a TC39 meeting (source) and is then added to the page with stage 0 proposals.

Stage 1: proposal

What is it? A formal proposal for the feature.

What’s required? A so-called champion must be identified who is responsible for the proposal. Either the champion or a co-champion must be a member of TC39 (source). The problem solved by the proposal must be described in prose. The solution must be described via examples, an API and a discussion of semantics and algorithms. Lastly, potential obstacles for the proposal must be identified, such as interactions with other features and implementation challenges. Implementation-wise, polyfills and demos are needed.

What’s next? By accepting a proposal for stage 1, TC39 declares its willingness to examine, discuss and contribute to the proposal. Going forward, major changes to the proposal are expected.

Stage 2: draft

What is it? A first version of what will be in the specification. At this point, an eventual inclusion of the feature in the standard is likely.

What’s required? The proposal must now additionally have a formal description of the syntax and semantics of the feature (using the formal language of the ECMAScript specification). The description should be as complete as possible, but can contain todos and placeholders. Two experimental implementations of the feature are needed, but one of them can be in a transpiler such as Babel.

What’s next? Only incremental changes are expected from now on.

Stage 3: candidate

What is it? The proposal is mostly finished and now needs feedback from implementations and users to progress further.

What’s required? The spec text must be complete. Designated reviewers (appointed by TC39, not by the champion) and the ECMAScript spec editor must sign off on the spec text. There must be at least two spec-compliant implementations (which don’t have to be enabled by default).

What’s next? Henceforth, changes should only be made in response to critical issues raised by the implementations and their use.

Stage 4: finished

What is it? The proposal is ready to be included in the standard.

What’s required? The following things are needed before a proposal can reach this stage:

What’s next? The proposal will be included in the ECMAScript specification as soon as possible. When the spec goes through its yearly ratification as a standard, the proposal is ratified as part of it.

Callbacks, Promises and async/await

Explain about promises in ES-6 including, the problems they solve, a quick explanation of the Promise API and:

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:

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 handlers being attached.

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

Example(s) that demonstrate how to avoid the callback hell (“Pyramid of Doom”)

Pyramid of Doom

doSomething(function(responseOne) {
    doSomethingElse(responseOne, function(responseTwo, err) {
        if (err) { handleError(err); }
        doMoreStuff(responseTwo, function(responseThree, err) {
            if (err) { handleAnotherError(err); }
            doFinalThing(responseThree, function(err) {
                if (err) { handleAnotherError(err); }
                // Complete
            }); // end doFinalThing
        }); // end doMoreStuff
    }); // end doSomethingElse
}); // end doSomething

Solution

doSomething()
.then(doSomethingElse)
.catch(handleError)
.then(doMoreStuff)
.then(doFinalThing)
.catch(handleAnotherError)

Example(s) that demonstrate how to execute asynchronous (promise-based) code in serial or parallel

var arrayOfPromises = [] // array containing promises

Promise.all(arrayOfPromises)
.then(function(arrayOfResults) {
    /* Do something when all Promises are resolved */
})
.catch(function(err) {
    /* Handle error is any of Promises fails */
})

Example(s) that demonstrate how to implement our own promise-solutions.

function get(url) {
  return new Promise(function(resolve, reject) {
    var req = new XMLHttpRequest();
    req.open('GET', url);
    req.onload = function() {
      if (req.status == 200) { 
          resolve(req.response); /* PROMISE RESOLVED */
      } else { 
          reject(Error(req.statusText)); /* PROMISE REJECTED */
      }
    };
    req.onerror = function() { reject(Error("Network Error")); };
    req.send();
  });
}

Example(s) that demonstrate error handling with promises

Since both the success and error functions are optional, we can split them into two .then()s for better readability.

get(url)
.then(function(response) {
    /* successFunction */
}, undefined)
.then(undefined, function(err) {
    /* errorFunction */
})

To make things even more readable, we make use of the .catch() method, which is a shorthand for a .then(undefined, errorFunction).

get(url)
.then(function(response) {
    /* successFunction */
})
.catch(function(err) {
    /* errorFunction */
})

Explain about JavaScripts async/await

How it relates to promises and reasons to use it compared to the plain promise API.

Async Await is syntactic sugar that changes the .then notation to more readable syntax. Instead of making a . connection between the promises the keyword awaitcan be used instead.

Provide examples to demonstrate:

Why this often is the preferred way of handling promises

function async myFunc() {
    const res = await fetch(...)
    const json = res.json()
    // ...
}

Error handling with async/await

function async myFunc() {
    try {
        const res = await fetch(...)
        const json = res.json()
        // ...
    } catch (err) {
        new Error(err)
    } 
}

Serial or parallel execution with async/await.

Async/await makes asynchronous code look and behave like synchronous code

async function SerialFlow(){
    let result1 = await doJob(1,1);
    let result2 = await doJob(2,2);
    let result3 = await doJob(3,3);
    let finalResult = result1+result2+result3;
    console.log(finalResult);
    return finalResult; 
}