1 of 100

Modern JavaScript beyond ES6

Nemanja Stojanovic

�LSE @ enki.com�@nem035 on the internet (nem035.com)

2 of 100

Why do we care?

🌕�🚀

3 of 100

Why do we care?

  • JavaScript is the lingua franca of the Web
  • (almost) every website ever made has some JavaScript running on it

4 of 100

Why do we care?

Github

  • #1 most starred language on Github (by far)

5 of 100

Why do we care?

https://octoverse.github.com/projects

  • most contributors in public and private repositories, organizations of all sizes, and every region of the world. ��4 years in a row 🎉

6 of 100

Why do we care?

NPM (registry of JS packages) is the largest package registry in the world

7 of 100

Why do we care?

NPM (registry of JS packages) is the largest package registry in the world

8 of 100

Why do we care?

According to Stack Overflow’s Annual Survey of 2018, for the sixth year in a row, JavaScript is the most commonly used programming language.

9 of 100

Why do we care?

(Jeff) Attwood’s Law (co-founder of StackOverflow):

any application that can be written in JavaScript, will eventually be written in JavaScript.

10 of 100

What can we code in JS?

  • Websites�
  • Mobile apps�
  • Backend servers�
  • IOT controllers�
  • Desktop apps

11 of 100

What is ECMAScript?

Quick History

  • JavaScript name is an attempt to capitalize on the success of Java.
  • Netscape submits JavaScript to the ECMA International Standards organization.
  • This results in a new language standard named ECMAScript.

  • JavaScript is the most popular implementation of that standard

12 of 100

What is ES6?

Quick History

  • ESX stands for ECMAScriptX
  • In 2009 the ES5 version of the standard is released
  • In 2015 the ES6 version of the standard is released
  • At the same time, a naming convention of ES<year-of-release> was established
  • “ES6” === “ES2015”

13 of 100

Why add new features?

  • Improve expressiveness (do more with less)

14 of 100

Why add new features?

  • Increase capabilities �(do more than before)

15 of 100

Why add new features?

  • Increase capabilities �(do more than before)

16 of 100

New features also allows us to do...

17 of 100

...fun meta things :)

18 of 100

Most features in latest ECMAScript releases are extensions to existing native functions

19 of 100

How does this work?

20 of 100

Functions - first class citizens

  • Behave like values (we can store them in variables, pass them as parameters etc.)

21 of 100

*.prototype.<method>

  • All instances of that function have access to it
  • Special object available to each function

22 of 100

*.prototype.<method>

  • Native functions behave the same

23 of 100

Static methods

  • Attached to the function and not on the prototype

  • Available via the function itself, not via instances of it

24 of 100

So what’s new in JS after ES6?

25 of 100

ECMAScript2016 (ES7)

*Smallest release with only 2 features

26 of 100

Array.prototype.includes

  • More declarative than Array.prototype.indexOf
  • Find if an item exists in an array

27 of 100

Array.prototype.includes

  • Works correctly with NaN

28 of 100

Array.prototype.includes

  • Takes an optional 2nd argument which is the index from which to start the search

29 of 100

** infix operator

  • Less verbose than Math.pow
  • Raise one number to the power of another

30 of 100

ECMAScript2017 (ES8)

31 of 100

Object.values

  • The counterpart to Object.keys
  • Get an array of object values

32 of 100

Object.values

33 of 100

Object.entries

  • Get an array of object key-value pairs

34 of 100

Object.entries

35 of 100

String.prototype.padStart

  • Pad a string with another string (from the left) until the resulting string reaches the given length

36 of 100

String.prototype.padEnd

  • Same as padStart except on the end (right) side of the string

37 of 100

padStart+padEnd

  • Print Pascal’s triangle�
    • Each number is the sum of the numbers directly above it.

38 of 100

padStart+padEnd

Output

39 of 100

Trailing commas in parameters

  • Syntax change that allows having a , after the last parameter

40 of 100

Trailing commas in parameters

  • Adding a new parameter allows us to add a new line without modifying the previous
  • Useful for version-control systems like Git �(gives simpler code-change diffs)

41 of 100

Trailing commas in parameters

  • Has no behavioral consequences

42 of 100

Async/await

  • Flow-control mechanism for promises
  • “Synchronous looking” async code

43 of 100

Async/await

  • Every async function returns a Promise
  • ...which we can await on in other async functions

44 of 100

Async/await

  • Works with try/catch

45 of 100

Before

After

46 of 100

ECMAScript2018 (ES9)

47 of 100

Rest vs Spread in ES6 ...

  • Rest gathers what’s remaining�
  • Spread expands what exists

48 of 100

Object rest (...) operator

  • Gather remaining object properties when destructuring

49 of 100

Object rest (...) operator

  • Remove unwanted properties

50 of 100

Object spread (...) operator

  • Perform a shallow clone

51 of 100

Promise.prototype.finally

  • Invoked when a promise is settled (either fulfilled, or rejected)

52 of 100

Promise.prototype.finally

  • Useful for cleanup (hiding spinners, closing file handles, etc)

53 of 100

Async iteration

  • for await of
  • Wait for each Promise to resolve before doing to the next iteration

54 of 100

How does async iteration work?

55 of 100

First thing’s first, how does sync iteration work?

  • Let’s build it!

56 of 100

How does iteration work?

  • We need to understand 3 concepts: iterable, iterator, and iteratorResult

57 of 100

What is an iterable?

  • Remember Symbol.iterator?
  • An object can mark itself as iterable by having a method whose key is Symbol.iterator

58 of 100

What is an iterator?

  • Invoking the method [Symbol.iterator()]() on an iterable returns an iterator

59 of 100

What is an iterator?

  • Iterator has method called next that returns the next iteratorResult each time it’s called

60 of 100

What is an iteratorResult?

  • An object wrapper around each item during an iteration
  • Contains the current item and a boolean indicating if we reach the end of the iteration

61 of 100

Let’s try it out!

62 of 100

Running a custom iterator

Manually

Using for of

63 of 100

No need for custom iterator.

Use ES6 generators

64 of 100

Ok but what about async iteration?

  • Symbol.asyncIterator to the rescue!
  • Method next of an async iterator wraps the iteratorResult in a Promise

65 of 100

Sync vs Async iterable

66 of 100

ECMAScript2018 brings us a lot of Regex goodies

67 of 100

What’s a regex?

  • String pattern matching

68 of 100

\s regex flag

  • “dotAll” flag (captures anything)

69 of 100

RegExp Named Group Captures

  • We can provide a name for a capture group

70 of 100

What is a capture group?

  • Anything wrapped in parenthesis

71 of 100

RegExp Named Capture Groups

  • We can provide a name for a capture group

72 of 100

RegExp Named Capture Groups

  • We can use /k to reference a named capture group within the regex itself

73 of 100

New RegExp lookaround

  • “Lookaround” in a Regex specifies what the surroundings of a location must look like

74 of 100

We already have RegExp look-ahead

  • Assert that what comes after does or does not exist

75 of 100

ES2018 gives us look-behind

  • Assert that what comes before does or does not exist

76 of 100

Look ahead

  • x(?=y) – positive (matches x when it's followed by y)
  • x(?!y) – negative (matches x when it's followed by y)

Look behind

  • (?<=x)y – positive (matches y when it's preceded by x)
  • (?<!x)y – negative (matches y when it's preceded by x)

77 of 100

Practical examples

78 of 100

79 of 100

80 of 100

RegExp unicode property escape

  • Match any unicode char based on its script

  • ES2015 introduced /u flag to match any unicode char

  • ES2018 adds /p{unicodeCharacterProperty} to match a particular unicode group

81 of 100

...we can also match emoji 🤓

82 of 100

The future is (almost) here

83 of 100

ECMAScript2019 (ES10)

84 of 100

String.prototype.matchAll()

  • Get all results matching a regex

85 of 100

How can we get all matches now?

86 of 100

How can we get all matches now?

87 of 100

String.prototype.matchAll()

  • Get all results matching a regex

88 of 100

String.prototype.matchAll()

  • Returns an iterator

89 of 100

String.prototype.matchAll()

  • Access to capture groups

90 of 100

Dynamic imports?

91 of 100

ES6 imports

  • Statically analyzable (linting, etc.)
  • Efficient bundling (tree-shaking, etc.)

92 of 100

Dynamic imports

  • Dynamically load parts of a JavaScript application at runtime

93 of 100

Dynamic imports

  • import() returns a Promise

94 of 100

Dynamic imports

  • Code-splitting
  • Improves performance (only load things when you need them => faster initial load)
  • Adjusting to factors only know at runtime

95 of 100

Array.prototype.flat()

  • Flatten a 2D array

96 of 100

Array.prototype.flat()

  • Only flattens one level

97 of 100

Array.prototype.flatMap()

  • Flatten a 2D array and map each element

98 of 100

String.prototype.trimStart()

String.prototype.trimEnd()

  • Only trim the left or right side of the string

99 of 100

Private class members

  • Denote fully private members of a class using the # prefix

100 of 100

Thank you

Nemanja Stojanovic

�LSE @ enki.com�@nem035 on the internet (nem035.com)