Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScript: Past, Present, and Future

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!

David Neal

April 08, 2022
Tweet

More Decks by David Neal

Other Decks in Programming

Transcript

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

    f * ( n + o ); NaN
  2. ( a + b ) + c = a +

    ( b + c ) // mathematically true > 0.1 + 0.2 === 0.3 false > ( a + b ) + c == a + ( b + c ) ??
  3. > typeof undefined // undefined > typeof true // boolean

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

    // false > null < 0 // false > null >= 0 // true > null <= 0 // true > Number( null ) // 0
  5. // undefined function troll() { return { haha: "ha!" };

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

    arr[10] = 3; arr.length // 11 arr[-1] = 4; arr.s = 5; arr.length // 11
  7. // 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" }
  8. // 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!
  9. // 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 }
  10. // 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' ]
  11. • Nullish coalescing ?? operator • Optional ?. chaining •

    Promise.allSettled() • Dynamic import()
  12. // 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
  13. // 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
  14. // 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
  15. // 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
  16. // Optional ?. Chaining const customer1 = {}; const customer2

    = { address: { city: "Nashville" } }; const city1 = customer1?.address?.city; // undefined const city2 = customer2?.address?.city; // Nashville
  17. // 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 ); } );
  18. // 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' } // ]
  19. // Dynamic import() const example = await import( "./importExample.js" );

    console.log( example ); // [Module: null prototype] { // default: { whatIsLove: [Function: whatIsLove] } // }
  20. // Old string replace() const qs = "q=what+is+love"; const nope

    = qs.replace( "+", " " ); // "q=what is+love”
  21. // 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"
  22. // 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"
  23. // 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 );
  24. // 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
  25. // 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 );
  26. // 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
  27. // Logical assignment operators // OR only assigns if x

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

    is a falsy value let x = false; x ||= "yes"; x ||= "what is"; // yes
  29. // 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";
  30. // 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
  31. // 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;
  32. // 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
  33. // Numeric separators example const numbersMakeMeSad = 10204005020405; const notSoBad

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

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

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

    "is", "love", "bacon", "don't", "hurt", "me" ]; console.log( arr.at( 3 ) ); // bacon
  37. // 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 ) );
  38. // 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
  39. // 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 ) );
  40. // 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
  41. // 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" );
  42. // 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
  43. // 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 } ); } }
  44. // Error _with_ a cause function shutUpAndDance() { try {

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

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

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

    static car = "Ferrari"; static #miles = 26000; static #getMiles() { Of86GlenbrookNorthHigh.#miles += 123; return Of86GlenbrookNorthHigh.#miles; } }
  48. // 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`; } }
  49. // 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() ); } }
  50. // 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
  51. // Private and static class members const myClass = new

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