David Neal
April 08, 2022
300

# JavaScript: Past, Present, and Future

Ah, JavaScript! Like it or not, it's a "tragically important" language that is "eating the world." Hate it? Love it? Avoid it? Embrace it?

This talk will be a parade of face-palm JavaScript fails, stupid JavaScript tricks, and bad jokes sure to get an eye-roll from everyone! Along the way, we may even learn a few mistakes to avoid and tips to make our own JavaScript less terrible!

April 08, 2022

## Transcript

1. ### > const lol = a + b + c –

f * ( n + o ); NaN

5. ### ( a + b ) + c = a +

( b + c ) // mathematically true > 0.1 + 0.2 === 0.3 false > ( a + b ) + c == a + ( b + c ) ??

7. ### > Math.round(0.4999999999999999722444243843710864894092082) 0 > Math.round(0.4999999999999999722444243843710864894092083) 1 I’ve got 99 problems

but JavaScript ain’t 1.0000000000000009

3, 4 ]
10. ### > typeof undefined // undefined > typeof true // boolean

> typeof "hello" // string > typeof 1 // number > typeof {lol:true} // object > typeof [1,2,3] // object > typeof null // object
11. ### > null == 0 // false > null > 0

// false > null < 0 // false > null >= 0 // true > null <= 0 // true > Number( null ) // 0

> NaN
13. ### > wat.test("javascript"); // true > wat.test("wat r u doin"); //

false > const wat = /a/g;
14. ### // undefined function troll() { return { haha: "ha!" };

} troll(); // automatic semi-colon
15. ### const arr = []; arr[1] = 1; arr[3] = 2;

arr[10] = 3; arr.length // 11 arr[-1] = 4; arr.s = 5; arr.length // 11
16. ### • trimStart() and trimEnd() • Optional Catch • Object.fromEntries() •

flat() and flatMap()
17. ### // String.prototype.trimStart() and trimEnd() const what = " \n \t

what is love".trimStart(); const bacon = "bacon don't hurt me\n \n \n \t ".trimEnd(); const obj = { lyric: what + " " + bacon }; console.log( obj ); // { lyric: "what is love bacon don't hurt me" }
18. ### // Optional Catch try { console.log( "Error objects?" ); throw

new Error( "LOL" ); } catch { console.log( "We don't need no stinkin' Error objects!" ); } // Error objects? // We don't need no stinkin' Error objects!
19. ### // Object.fromEntries() const props = [ [ "what", "is love"

], [ "bacon", "don't hurt me" ], [ "love", true ] ]; const obj = Object.fromEntries( props ); console.log( obj ); // { what: 'is love', bacon: "don't hurt me", love: true }
20. ### // Array.prototype.flat() and .flatMap() const nestedArrays = [ "bacon", "eggs",

[ "waffles" ], [ "coffee" ], [ "doughnuts", "milk" ] ]; const flattened = nestedArrays.flat(); console.log( flattened ); // [ 'bacon', 'eggs', 'waffles', 'coffee', 'doughnuts', 'milk' ]
21. ### • Nullish coalescing ?? operator • Optional ?. chaining •

Promise.allSettled() • Dynamic import()
22. ### // Logical OR || operator works with any falsy value

console.log( 0 || "zero value" ); // zero value console.log( "" || "empty string value" ); // empty string value console.log( false || "false value" ); // false value console.log( null || "null value" ); // null value console.log( undefined || "undefined value" ); // undefined value
23. ### // Nullish (??) operator only works with null/undefined console.log( 0

?? "zero value" ); // 0 console.log( "" ?? "empty string value" ); // "" console.log( false ?? "false value" ); // false console.log( null ?? "null value" ); // null value console.log( undefined ?? "undefined value" ); // undefined value
24. ### // The old way of checking for potentially missing properties

const customer = {}; let city; try { city = customer.address.city; } catch ( err ) { console.log( err ); // TypeError: Cannot read properties of undefined (reading 'city’) } console.log( city ); // undefined
25. ### // The old way of checking for potentially missing properties

const customer = {}; let city; if ( customer && customer.address && customer.address.city ) { city = customer.address.city; } console.log( city ); // undefined
26. ### // Optional ?. Chaining const customer1 = {}; const customer2

= { address: { city: "Nashville" } }; const city1 = customer1?.address?.city; // undefined const city2 = customer2?.address?.city; // Nashville
27. ### // Promise.allSettled() const p1 = new Promise( ( resolve, reject

) => { setTimeout( () => { resolve( "p1 resolved" ); }, 250 ); } ); const p2 = new Promise( ( resolve, reject ) => { setTimeout( () => { resolve( "p2 resolved" ); }, 450 ); } ); const p3 = new Promise( ( resolve, reject ) => { setTimeout( () => { reject( "p3 rejected" ); }, 650 ); } );
28. ### // Promise.allSettled() const results = await Promise.allSettled( [ p1, p2,

p3 ] ); console.log( results ); // [ // { status: 'fulfilled', value: 'p1 resolved' }, // { status: 'fulfilled', value: 'p2 resolved' }, // { status: 'rejected', reason: 'p3 rejected' } // ]
29. ### // Dynamic import() const example = await import( "./importExample.js" );

console.log( example ); // [Module: null prototype] { // default: { whatIsLove: [Function: whatIsLove] } // }
30. ### • String.prototype.replaceAll() • Promise.any() • Logical assignment operators ||= &&=

??= • Numeric separator
31. ### // Old string replace() const qs = "q=what+is+love"; const nope

= qs.replace( "+", " " ); // "q=what is+love”
32. ### // Old string replace() const qs = "q=what+is+love"; const nope

= qs.replace( "+", " " ); // "q=what is+love” const yep = qs.replace( /\+/g, " " ); // "q=what is love"
33. ### // Old string replace() const qs = "q=what+is+love"; const nope

= qs.replace( "+", " " ); // "q=what is+love” const yep = qs.replace( /\+/g, " " ); // "q=what is love" const lol = qs.split( "+" ).join( " " ); // "q=what is love"
34. ### // String.prototype.replaceAll() const n00b = "Hey, I can leet speak,

too, yo"; const l33t = n00b.replaceAll( "e", "3" ) .replaceAll( "o", "0" ) .replaceAll( ",", "" ) .toLowerCase(); console.log( l33t );
35. ### // String.prototype.replaceAll() const n00b = "Hey, I can leet speak,

too, yo"; const l33t = n00b.replaceAll( "e", "3" ) .replaceAll( "o", "0" ) .replaceAll( ",", "" ) .toLowerCase(); console.log( l33t ); // h3y i can l33t sp3ak t00 y0
36. ### // Promise.any() example const p1 = new Promise( res =>

{ setTimeout( () => { res( "knock, knock" ); }, 200 ); } ); const p2 = new Promise( res => { setTimeout( () => { res( "who's there?" ); }, 400 ); } ); const interruptingCow = Promise.reject( "MOO!!" ); const lol = await Promise.any( [ p1, p2, interruptingCow ] ); console.log( lol );
37. ### // Promise.any() example const p1 = new Promise( res =>

{ setTimeout( () => { res( "knock, knock" ); }, 200 ); } ); const p2 = new Promise( res => { setTimeout( () => { res( "who's there?" ); }, 400 ); } ); const interruptingCow = Promise.reject( "MOO!!" ); const lol = await Promise.any( [ p1, p2, interruptingCow ] ); console.log( lol ); // knock, knock
38. ### // Logical assignment operators // OR only assigns if x

is a falsy value let x = false; x ||= "yes"; x ||= "what is";
39. ### // Logical assignment operators // OR only assigns if x

is a falsy value let x = false; x ||= "yes"; x ||= "what is"; // yes
40. ### // Logical assignment operators // OR only assigns if x

is a falsy value let x = false; x ||= "yes"; x ||= "what is"; // yes // AND assigns if y is not a falsy value let y = "gimme-all-yer"; y &&= "i love";
41. ### // Logical assignment operators // OR only assigns if x

is a falsy value let x = false; x ||= "yes"; x ||= "what is"; // yes // AND assigns if y is not a falsy value let y = "gimme-all-yer"; y &&= "i love"; // i love
42. ### // Logical assignment operators // OR only assigns if x

is a falsy value let x = false; x ||= "yes"; x ||= "what is"; // yes // AND assigns if y is not a falsy value let y = "gimme-all-yer"; y &&= "i love"; // i love // ??= Nullish only assigns if z is null or undefined let z = "bacon"; z ??= y;
43. ### // Logical assignment operators // OR only assigns if x

is a falsy value let x = false; x ||= "yes"; x ||= "what is"; // yes // AND assigns if y is not a falsy value let y = "gimme-all-yer"; y &&= "i love"; // i love // ??= Nullish only assigns if z is null or undefined let z = "bacon"; z ??= y; // bacon

45. ### // Numeric separators example const numbersMakeMeSad = 10204005020405; const notSoBad

= 10_204_005_020_405;
46. ### // Numeric separators example const numbersMakeMeSad = 10204005020405; const notSoBad

= 10_204_005_020_405; console.log( numbersMakeMeSad === notSoBad ); // true
47. ### • Array.prototype.at() & String .at() • Top-level await • Error

cause • New static, private class members
48. ### // String and Array at() const arr = [ "what",

"is", "love", "bacon", "don't", "hurt", "me" ]; console.log( arr.at( 3 ) );
49. ### // String and Array at() const arr = [ "what",

"is", "love", "bacon", "don't", "hurt", "me" ]; console.log( arr.at( 3 ) ); // bacon
50. ### // String and Array at() const arr = [ "what",

"is", "love", "bacon", "don't", "hurt", "me" ]; console.log( arr.at( 3 ) ); // bacon console.log( arr.at( -1 ) );
51. ### // String and Array at() const arr = [ "what",

"is", "love", "bacon", "don't", "hurt", "me" ]; console.log( arr.at( 3 ) ); // bacon console.log( arr.at( -1 ) ); // me
52. ### // String and Array at() const arr = [ "what",

"is", "love", "bacon", "don't", "hurt", "me" ]; console.log( arr.at( 3 ) ); // bacon console.log( arr.at( -1 ) ); // me const msg = "I love rock n' roll"; console.log( msg.at( 4 ) );
53. ### // String and Array at() const arr = [ "what",

"is", "love", "bacon", "don't", "hurt", "me" ]; console.log( arr.at( 3 ) ); // bacon console.log( arr.at( -1 ) ); // me const msg = "I love rock n' roll"; console.log( msg.at( 4 ) ); // v
54. ### // Top-level await async function sleep( ms ) { const

msg = `I slept for \${ ms } milliseconds`; return new Promise( resolve => setTimeout( () => resolve( msg ), ms ) ); } const result = await sleep( 500 ); console.log( result ); console.log( "finished" );
55. ### // Top-level await async function sleep( ms ) { const

msg = `I slept for \${ ms } milliseconds`; return new Promise( resolve => setTimeout( () => resolve( msg ), ms ) ); } const result = await sleep( 500 ); console.log( result ); console.log( "finished" ); // I slept for 500 milliseconds // finished
56. ### // Error _with_ a cause function breakin() { throw new

Error( "Gonna stop you cold" ); } function breakin2ElectricBoogaloo() { try { breakin(); } catch ( err ) { throw new Error( "Whacked", { cause: err } ); } }
57. ### // Error _with_ a cause function shutUpAndDance() { try {

breakin2ElectricBoogaloo(); } catch ( err ) { console.log( err ); } } shutUpAndDance();
58. ### // Error _with_ a cause shutUpAndDance(); // Error: Whacked //

at breakin2ElectricBoogaloo ... // [cause]: Error: Gonna stop you cold // at breakin ... // }
59. ### // Private and static class members class Of86GlenbrookNorthHigh { #reason;

static car = "Ferrari"; static #miles = 26000; constructor( reason ) { this.#reason = reason; } ... }
60. ### // Private and static class members class Of86GlenbrookNorthHigh { #reason;

static car = "Ferrari"; static #miles = 26000; static #getMiles() { Of86GlenbrookNorthHigh.#miles += 123; return Of86GlenbrookNorthHigh.#miles; } }
61. ### // Private and static class members class Of86GlenbrookNorthHigh { #reason;

static car = "Ferrari"; static #miles = 26000; static #getMiles() { … } #carStatus() { const miles = Of86GlenbrookNorthHigh.#getMiles(); return `The \${ Of86GlenbrookNorthHigh.car } has \${ miles } miles`; } }
62. ### // Private and static class members class Of86GlenbrookNorthHigh { #carStatus()

{ … } status() { console.log( `Ferris can't go to school, he's \${ this.#reason }` ); console.log( this.#carStatus() ); } }
63. ### // Private and static class members const myClass = new

Of86GlenbrookNorthHigh( "sick" ); myClass.status(); // Ferris can't go to school, he's sick // The Ferrari has 26123 miles
64. ### // Private and static class members const myClass = new

Of86GlenbrookNorthHigh( "sick" ); myClass.status(); myClass.#carStatus(); // SyntaxError console.log( myClass.#car ); // SyntaxError