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!

Avatar for David Neal

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