How to write JavaScript code for .NET Developer in 2018

We are were on the same side...

Fragments from my bio related to MS tech stack

  • 1994 - Fist commercial project - QBASIC
  • 1997 - Started web development (MS FrontPage)
  • 1999-2005 - Developing Windows Client-Server apps (Delphi, developer, tech lead+pm+architect)
  • 2004 -2015 - ko.com.ua/user/100 - Journalist, most articles on MS development tools and tech
  • 2005 - Started C#/.NET development
  • 2007-2010 - Dou.ua - editor, author on .NET tech stack
  • 2007-2012 - Founder and Leader Sumy .NET User Group
  • 2010-2012 - Windows Phone, Silverlight
  • 2013 - SoftServe IT Academy (.NET direction)
  • 2013-2014 - First MS IT Academy in Crimea
  • 2014-2015 - SLIMCARD Startup (MS BizSpark, Azure)
  • 2016 - Programming Mentor project

How to distinguish Java developer from .NET developer while they write JavaScript code? 

Java

.NET

What's wrong here?

Cause of evil...

back-end

front-end

"...when you write JavaScript code,

you do it without respect"

-Vito Andolini Corleone

The problem is...

JavaScript is likely not what you think it is

Which programming languages are most similar to JavaScript?

Scheme to JavaScript

Understanding language philosopy

Key concepts

Dynamic

language

Function is first-class citizen

Prototype-based OO

Event loop based concurrency

JS Data Types

Primitives:

  1. Number
  2. Boolean
  3. String
  4. undefined
  5. null
  6. Object
  7. Symbol

Built-in Objects (some of):

  1. Function
  2. Array
  3. RegExp
  4. Map
  5. Set
  6. Proxy
  7. Generator

?

[]+[]
""

?

{}+{}
"[object Object][object Object]"

?

[]+{}
"[object Object]"

?

{}+[]
0

?

({}+[])
"[object Object]"

Function is First-Class Citizen

function counter() {
  let val = 0;
  return function() {
    return ++val;
  }
}

const c = counter();
console.log(c()); // 1
console.log(c()); // 2
console.log(c()); // 3

Prototype-Based OO

Event Loop Based Concurrency

Writing JS
modern way

  1. ES1

  2. ES2

  3. ES3

  4. ES5

  5. ES5.1

Complete list of EcmaScript Editions

  1. ES2015

  2. ES2016

  3. ES2017

  4. ES2018

ES2015

var vs let vs const

Swap values - ES5

var a = 1, b = 2;

// Junior
var tmp = b;
b = a;
a = tmp;

// Intermediate
a ^= b;
b ^= a;
a ^= b;

// Senior
a = [b, b=a][0];

// Architect
b = (function(a){return a})(a, a=b);

Swap values - ES2015+

let a = 1, b = 2;

[a, b] = [b, a]

Generate array

function seq(n) {
  var result = [];
  for (var i = 0; i < n; i++) {
      result.push(i);
  }
  return result;
}

ES5

[0, 1, 2, 3, ..., N-1]

Generate array

ES2015

const seq = n => [...Array(n).keys()];
[0, 1, 2, 3, ..., N-1]

Async code

callbacks

callback hell

const addOneTo = function(number, callback) {
    const result = number + 1;
    if (callback) {
        callback(result);
    }
}
// 5 + 1 = 6
addOneTo(5, function(res){
    console.log(res);
})
// 5 + 1 + 1 + 1 + 1 + 1 = 10
addOneTo(5, function(res1) {
    addOneTo(res1, function(res2) {
        addOneTo(res2, function(res3) {
            addOneTo(res3, function(res4) {
                addOneTo(res4, function(res5) {
                    console.log(res5);
                });
            });
        });
    });
});

ES2015: promises

const addOneTo = function(number) {
    const result = number + 1;
    return new Promise(function(resolve, reject) {
        resolve(result);
    });
}
// 5 + 1 = 6
addOneTo(5)
    .then( res => console.log(res) );
// 5 + 1 + 1 + 1 + 1 + 1 = 10
addOneTo(5)
    .then(addOneTo)
    .then(addOneTo)
    .then(addOneTo)
    .then(addOneTo)
    .then(console.log)

ES2017: async/await

const addOnTo = function(number){
    const result = number + 1;
    return new Promise(function(resolve, reject) {
        resolve(result);
    });
}
async function calc(){
    const res1 = await addOnTo(5);
    const res2 = await addOnTo(res1);
    const res3 = await addOnTo(res2);
    const res4 = await addOnTo(res3);
    const res5 = await addOnTo(res4);
    console.log(res5);
}
calc();

Observables

<input id="inpt" type="text" >
<h3>You entered:</h3>
<div id="results"></div>
Rx.Observable
  .fromEvent(inpt, 'keyup')
  .map(x => x.currentTarget.value)
  .debounceTime(500) 
  .subscribe(x => result.innerHTML += `<br>${x}`);

RxJS Sample

Functional

Approach

What's wrong with this code?

function seq(n) {
  var result = [];
  for (var i = 0; i < n; i++) {
      result.push(i);
  }
  return result;
}
const seq = n => [...Array(n).keys()];

Simple steps to adopt functional approach in JS

  1. Build pure functions 
  2. Use constants where possible 
  3. Avoid loops
  • Consider the numbers 6969 and 9116. When you rotate them 180 degrees (upside down), these numbers remain the same.
  • To clarify, if we write them down on a paper and turn the paper upside down, the numbers will be the same. Try it and see! Some numbers such as 2 or 5 don't yield numbers when rotated.
  • Given a range, return the count of upside down numbers within that range. For example, solve(0,10) = 3, because there are only 3 upside down numbers >= 0 and < 10. They are 0, 1, 8.

Sample task: upside down

function solve(x, y) {
  let total = 0;
  for (let i = x; i < y; i++) {
    let current = i.toString();
    let final = '';
    let split = current.split('').reverse();
    for (let j = 0; j < split.length; j++) {
      let x = split[j];
      if (x === '0' || x === '1' || x === '8') {
        final += x;
      } else if (x === '6') {
        final += '9';
      } else if (x === '9') {
        final += '6';
      } else {
        break;
      }
    }
    if (final === current) {
      total++;
    }
  }
  return total;
};

Sample: non-functional

function solve(x, y) {
 return [...'_'.repeat(y - x + 1)]
    .map( (_,i) => x + i )
    .reduce( (acc, n) => n == rotate(n) ? ++acc : acc, 0 );
};

function rotate(num) {
  const digitsRotated = {'0': '0', '1': '1', '6': '9', '8': '8', '9': '6'};
  return String(num)
    .split('')
    .reverse()
    .map(d => digitsRotated[d])
    .join('');
}

Sample: functional

Going Deeper...

const sumBelow = (number, sum = 0) => (
  number === 0 
    ? sum
    : sumBelow(number - 1, sum + number)
)

Consider the code

console.log(sumBelow(1000));
console.log(sumBelow(10000));

Sometimes in future...

const trampoline = fn => (...args) => {
  let result = fn(...args)
  
  while (typeof result === 'function') {
    result = result()
  }
  
  return result
}

const sumBelowRec = (number, sum = 0) => (
  number === 0
    ? sum
    : () => sumBelowRec(number - 1, sum + number)
)

Trampoline

const sumBelow = trampoline(sumBelowRec);
console.log(sumBelow(10000));
console.log(sumBelow(100000));
console.log(sumBelow(1000000));

TypeScript

TypeScript: good parts

  • Microsoft :)
  • Anders Hejlsberg
  • Type annotations and compile-time type checking
  • Type inference
  • Type erasure
  • Interfaces
  • Enumerated type
  • Generics
  • Namespaces
  • Tuples
  • Async/Await

Welcome to the light side!

"Learning Web Development"

community on FB

Thank you!

dot-net-js-2018

By Programming Mentor (Vyacheslav Koldovskyy)