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

I didn't know that!

I didn't know that!

stefan judis

July 19, 2018
Tweet

More Decks by stefan judis

Other Decks in Technology

Transcript

  1. @stefanjudis
    I didn't know that!

    View full-size slide

  2. My first job
    interview

    View full-size slide


  3. We're running a Magento
    shop combined with a
    CouchDB and a Frontend
    application with a Prototype/
    jQuery mix.

    View full-size slide


  4. We're running a Magento
    shop combined with a
    CouchDB and a Frontend
    application with a Prototype/
    jQuery mix.

    View full-size slide


  5. We're running a Magento
    shop combined with a
    CouchDB and a Frontend
    application with a Prototype/
    jQuery mix.

    View full-size slide


  6. We're running a Magento
    shop combined with a
    CouchDB and a Frontend
    application with a Prototype/
    jQuery mix.
    I didn't say that I
    didn't know
    most of these
    technologies...

    View full-size slide

  7. ... which lead to
    enormous stress.

    View full-size slide

  8. 8 years later

    View full-size slide

  9. The dangerous
    knowledge
    comparison

    View full-size slide

  10. What I think
    others know
    What I
    know

    View full-size slide

  11. Web Development

    View full-size slide

  12. You can't know
    everything!

    View full-size slide


  13. Don’t Compare Your
    Behind-The-Scenes With
    Everyone's Highlight Reel.
    by Tara Hunt

    View full-size slide

  14. Know where to look
    for information

    View full-size slide

  15. The learning journey 

    won't end.

    View full-size slide

  16. TIL: ...
    (Today I learned: ...)

    View full-size slide

  17. But then I learned
    it's deprecated...

    View full-size slide

  18. Twitter is neither a
    bookmarking nor
    documentation tool!

    View full-size slide

  19. Write it down!
    Quick'n'dirty!

    View full-size slide

  20. My learnings
    in 2 years
    (a random list in no particular order)
    (not always useful)

    View full-size slide

  21. NaNNaNNaN
    NaNNaN

    View full-size slide

  22. parseInt('Hello world', 10)

    View full-size slide

  23. parseInt('Hello world', 10)
    NaN

    View full-size slide

  24. parseInt('Hello world', 10)
    NaN === NaN
    false

    View full-size slide

  25. isNaN(NaN); // true

    View full-size slide

  26. isNaN(NaN); // true
    isNaN(undefined); // true
    isNaN({}); // true
    isNaN(true); // false
    isNaN(null); // false
    isNaN(37); // false

    View full-size slide

  27. isNaN(NaN); // true
    isNaN(undefined); // true
    isNaN({}); // true
    isNaN(true); // false
    isNaN(null); // false
    isNaN(37); // false
    function myIsNaN(value) {
    return value !== value;
    }

    View full-size slide

  28. isNaN(NaN); // true
    isNaN(undefined); // true
    isNaN({}); // true
    isNaN(true); // false
    isNaN(null); // false
    isNaN(37); // false
    myIsNaN(NaN); // true
    myIsNaN(undefined); // false
    myIsNaN({}); // false
    myIsNaN(true); // false
    myIsNaN(null); // false
    myIsNaN(37); // false

    View full-size slide

  29. isNaN(NaN); // true
    isNaN(undefined); // true
    isNaN({}); // true
    isNaN(true); // false
    isNaN(null); // false
    isNaN(37); // false
    myIsNaN(NaN); // true
    myIsNaN(undefined); // false
    myIsNaN({}); // false
    myIsNaN(true); // false
    myIsNaN(null); // false
    myIsNaN(37); // false
    Number.isNaN(NaN); // true
    Number.isNaN(undefined); // false
    Number.isNaN({}); // false
    Number.isNaN(true); // false
    Number.isNaN(null); // false
    Number.isNaN(37); // false

    View full-size slide

  30. isNaN(NaN); // true
    isNaN(undefined); // true
    isNaN({}); // true
    isNaN(true); // false
    isNaN(null); // false
    isNaN(37); // false
    myIsNaN(NaN); // true
    myIsNaN(undefined); // false
    myIsNaN({}); // false
    myIsNaN(true); // false
    myIsNaN(null); // false
    myIsNaN(37); // false
    Number.isNaN(NaN); // true
    Number.isNaN(undefined); // false
    Number.isNaN({}); // false
    Number.isNaN(true); // false
    Number.isNaN(null); // false
    Number.isNaN(37); // false
    Object.is(NaN, NaN); // true
    Object.is(undefined, NaN); // false
    Object.is({}, NaN); // false
    Object.is(true, NaN); // false
    Object.is(null, NaN); // false
    Object.is(37, NaN); // false

    View full-size slide

  31. Object.is?
    ===
    +
    SPECIAL HANDLING OF
    NaN, -0, +0

    View full-size slide

  32. Object.is?
    Object.is(-0, 0); // false
    Object.is(NaN, NaN); // true
    SameValue Comparison

    View full-size slide

  33. ['foo', 123, true, undefined, NaN].indexOf(NaN)
    ['foo', 123, true, undefined, NaN].includes(NaN)
    true
    ['foo', 123, true, undefined, -0].includes(0)
    true
    SameValueZero Comparison
    -1

    View full-size slide

  34. Abstract Equality Comparison
    Equality comparison and sameness
    ==
    Strict Equality Comparison ===, indexOf, ...
    SameValueZero includes, ...
    SameValue Object.is, ...

    View full-size slide

  35. developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness

    View full-size slide

  36. Should I
    (force) push it?

    View full-size slide

  37. $ history | grep amend
    53 git co -p --amend index.html
    69 git co -p --amend
    71 git co -p --amend content/blueprints
    1538 git co -p --amend
    1540 git co -p --amend migration-tests
    1542 git co -p --amend migration-tests
    1545 git co -p --amend test_app.py
    1627 git co -p --amend
    1842 git co --amend
    1845 git co --amend
    1941 git co --amend
    2273 git co -p --amend
    ...

    View full-size slide

  38. $ git co -p --amend index.html
    $ git push -f origin some-feature

    View full-size slide

  39. $ git co -p --amend index.html
    $ git push -f origin some-feature
    It's very easy to overwrite
    remote changes with
    force pushing!

    View full-size slide

  40. developer.atlassian.com/blog/2015/04/force-with-lease/

    View full-size slide

  41. Process
    substitution

    View full-size slide

  42. Process substitution
    $ bash <(curl -s https://codecov.io/bash)

    View full-size slide


  43. Process substitution allows a
    process’s input or output to be
    referred to using a filename.

    View full-size slide

  44. $ echo <(ls .)
    /dev/fd/11

    View full-size slide

  45. $ cat <(ls .)
    functions.sh
    .zshrc
    ...

    View full-size slide

  46. $ node <(echo 'console.log("foo")')
    foo

    View full-size slide

  47. $ node <(pbpaste)
    foo

    View full-size slide

  48. $ node <(pbpaste)
    foo
    console.log("foo")
    But then I learned you
    can pipe into Node.js

    View full-size slide

  49. $ node <(pbpaste)
    foo

    View full-size slide

  50. $ pbpaste | node
    foo

    View full-size slide

  51. Break
    zooming with
    one line

    View full-size slide

  52. body {
    font-size: 2vw;
    }

    View full-size slide

  53. body {
    font-size: calc(1vw + 1em);
    }

    View full-size slide

  54. Stylesheets do
    not only block
    rendering

    View full-size slide


  55. app.css
    START RENDER

    View full-size slide


  56. <br/>var script = document.createElement('script');<br/>script.src = "analytics.js";<br/>document.getElementsByTagName('head')[0].appendChild(script);<br/>

    View full-size slide


  57. <br/>var script = document.createElement('script');<br/>script.src = "analytics.js";<br/>document.getElementsByTagName('head')[0].appendChild(script);<br/>
    app.css
    analytics.js

    View full-size slide

  58. <br/>var script = document.createElement('script');<br/>script.src = "analytics.js";<br/>document.getElementsByTagName('head')[0].appendChild(script);<br/>



    app.css
    analytics.js

    View full-size slide

  59. {
    'ü': 'foo',
    'ü': 'bar',
    '': 'baz',
    '': 'wat!'
    }

    View full-size slide

  60. {
    'ü': 'foo',
    'u\u0308': 'bar',
    '': 'baz',
    '': 'wat!'
    }

    View full-size slide

  61. {
    'ü': 'foo',
    'u\u0308': 'bar',
    '': 'baz',
    '\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC66': 'wat!'
    }

    View full-size slide


  62. Two IdentifierName that are
    canonically equivalent according
    to the Unicode standard are not
    equal unless they are represented
    by the exact same sequence of
    code units.

    View full-size slide


  63. Two IdentifierName that are
    canonically equivalent according
    to the Unicode standard are not
    equal unless they are represented
    by the exact same sequence of
    code units.

    View full-size slide

  64. Unicode is
    powerful and
    very fascinating
    (and scary)

    View full-size slide

  65. https://www.fileformat.info/info/unicode/char/202e/index.htm

    View full-size slide

  66. "Logical" string
    comparisons

    View full-size slide

  67. 'aBcD' === 'abcd'

    View full-size slide

  68. 'aBcD' === 'abcd' // false

    View full-size slide

  69. 'aBcD' === 'abcd' // false
    'ábcd' === 'abcd'

    View full-size slide

  70. 'aBcD' === 'abcd' // false
    'ábcd' === 'abcd' // false

    View full-size slide

  71. 'aBcD' === 'abcd' // false
    'ábcd' === 'abcd' // false
    'Price 2€' > 'Price 1€'

    View full-size slide

  72. 'aBcD' === 'abcd' // false
    'ábcd' === 'abcd' // false
    'Price 2€' > 'Price 1€' // true

    View full-size slide

  73. 'aBcD' === 'abcd' // false
    'ábcd' === 'abcd' // false
    'Price 2€' > 'Price 1€' // true
    'Price 20€' > 'Price 3€'

    View full-size slide

  74. 'aBcD' === 'abcd' // false
    'ábcd' === 'abcd' // false
    'Price 2€' > 'Price 1€' // true
    'Price 20€' > 'Price 3€' // false

    View full-size slide

  75. localCompare
    'aBcD'.localeCompare('abcd', undefined, { sensitivity: 'base' }) // 0
    'ábcd'.localeCompare('abcd', undefined, { sensitivity: 'base' }) // 0

    View full-size slide

  76. localCompare
    a ≠ b, a = á, a = A
    'aBcD'.localeCompare('abcd', undefined, { sensitivity: 'base' }) // 0
    'ábcd'.localeCompare('abcd', undefined, { sensitivity: 'base' }) // 0

    View full-size slide

  77. localCompare
    'Price 2€'.localeCompare('Price 3€', undefined, { numeric: true }) // -1
    'Price 3€'.localeCompare('Price 3€', undefined, { numeric: true }) // 0
    'Price 23€'.localeCompare('Price 3€', undefined, { numeric: true }) // 1

    View full-size slide

  78. localCompare
    'Price 2€'.localeCompare('Price 3€', undefined, { numeric: true }) // -1
    'Price 3€'.localeCompare('Price 3€', undefined, { numeric: true }) // 0
    'Price 23€'.localeCompare('Price 3€', undefined, { numeric: true }) // 1
    "1" < "2" < "10"

    View full-size slide

  79. How to
    center
    elements

    View full-size slide

  80. .center {
    display: flex;
    align-items: center;
    justify-content: center;
    }

    View full-size slide

  81. .center {
    display: flex;
    align-items: center;
    justify-content: center;
    }
    .center-using-grid {
    display: grid;
    align-items: center;
    justify-items: center;
    }

    View full-size slide

  82. .center {
    display: flex;
    align-items: center;
    justify-content: center;
    }
    .center-using-grid {
    display: grid;
    place-items: center;
    }

    View full-size slide

  83. .center {
    display: flex;
    align-items: center;
    justify-content: center;
    }
    .center-using-grid {
    display: grid;
    place-items: center;
    }
    2 declarations!

    View full-size slide

  84. developer.mozilla.org/en-US/docs/Web/CSS/place-items
    place-items
    support

    View full-size slide

  85. Querying the DOM
    is not equal
    querying the DOM

    View full-size slide


  86. foo
    bar
    baz

    document.querySelectorAll('li');
    // NodeList(3) [li, li, li]

    View full-size slide


  87. foo
    bar
    baz

    document.querySelectorAll('li');
    // NodeList(3) [li, li, li]
    document.getElementsByTagName('li');
    // HTMLCollection(3) [li, li, li]

    View full-size slide


  88. foo
    bar
    baz

    NodeList(3) HTMLCollection(3)

    View full-size slide


  89. foo
    bar
    baz
    wat

    NodeList(3) HTMLCollection(4)

    View full-size slide


  90. foo
    bar
    baz
    wat

    NodeList(3) HTMLCollection(4)
    There are live and
    static element
    collections

    View full-size slide

  91. document.querySelectorAll
    // static NodeList

    View full-size slide

  92. document.querySelectorAll
    // static NodeList
    element.childNodes
    // live NodeList

    View full-size slide

  93. document.querySelectorAll
    // static NodeList
    element.childNodes
    // live NodeList
    element.children
    // (live) HTMLCollection

    View full-size slide

  94. document.querySelectorAll
    // static NodeList
    element.childNodes
    // live NodeList
    element.children
    // (live) HTMLCollection
    document.getElementsByTagName
    // (live) HTMLCollection

    View full-size slide

  95. www.stefanjudis.com/blog/accessing-the-dom-is-not-equal-accessing-the-dom

    View full-size slide

  96. WAT!!!
    (part 2)

    View full-size slide

  97. Fooo
    Some more information

    #foo:hover {
    background: DeepSkyBlue;
    }

    View full-size slide


  98. Document languages may define
    additional ways in which an
    element can match :hover. For
    example, [HTML5] defines a labeled
    control element as matching :hover
    when its label is hovered.

    View full-size slide


  99. Document languages may define
    additional ways in which an
    element can match :hover. For
    example, [HTML5] defines a labeled
    control element as matching :hover
    when its label is hovered.

    View full-size slide

  100. kizu.ru/en/blog/label-to-input/

    View full-size slide

  101. Regular
    expressions

    View full-size slide

  102. const regex = /Jane.Smith/;
    regex.test('Jane Smith'); // true
    regex.test('Jane\nSmith'); // false

    View full-size slide

  103. const regex = /Jane.Smith/;
    regex.test('Jane Smith'); // true
    regex.test('Jane\nSmith'); // false
    '.' doesn't actually
    match all characters!

    View full-size slide

  104. const regex = /Jane.Smith/;
    regex.test('Jane Smith'); // true
    regex.test('Jane\nSmith'); // false

    View full-size slide

  105. const regex = /Jane.Smith/s;
    regex.test('Jane Smith'); // true
    regex.test('Jane\nSmith'); // true

    View full-size slide

  106. github.com/tc39/proposal-regexp-dotall-flag

    View full-size slide

  107. *
    * use with Babel
    dotall flag
    support
    *
    *

    View full-size slide

  108. const regex = /Jane.Smith/;

    View full-size slide

  109. const regex = /(Jane|John).(Smith|Miller)/;
    'John Smith'.match(regex);
    // [ "John Smith", "John", "Smith" ]

    View full-size slide

  110. const regex = /(Jane|John).(Smith|Miller)/;
    'John Smith'.match(regex);
    // [ "John Smith", "John", "Smith" ]

    View full-size slide

  111. const regex = /(?:Jane|John).(Smith|Miller)/;
    'John Smith'.match(regex);
    // [ "John Smith","Smith" ]

    View full-size slide

  112. const regex = /(?:Jane|John).(Smith|Miller)/;
    'John Smith'.match(regex);
    // [ "John Smith","Smith" ]
    There are
    non-capturing groups
    in JavaScript

    View full-size slide

  113. Why we
    won't have
    element queries

    View full-size slide

  114. Why we (probably)
    won't have
    element queries

    View full-size slide

  115. .mod img {
    display: block;
    margin: 0 auto;
    width: 100%;
    max-width: 250px;
    }

    View full-size slide

  116. .mod img {
    display: block;
    margin: 0 auto;
    width: 100%;
    max-width: 250px;
    }
    .mod:media( min-width: 425px ) img {
    float: left;
    width: 30%;
    max-width: 9999px;
    }

    View full-size slide

  117. .box {
    width: 1200px;
    }

    View full-size slide

  118. .box {
    width: 1200px;
    }

    View full-size slide

  119. .box {
    width: 1200px;
    }
    .box:media(min-width: 1200px) {
    width: 1000px;
    }

    View full-size slide

  120. .box {
    width: 1200px;
    }
    .box:media(min-width: 1200px) {
    width: 1000px;
    }

    View full-size slide

  121. .box {
    width: 1200px;
    }
    .box:media(min-width: 1200px) {
    width: 1000px;
    }

    View full-size slide

  122. .box {
    width: 1200px;
    }
    .box:media(min-width: 1200px) {
    width: 1000px;
    }

    View full-size slide

  123. .box {
    width: 1200px;
    }
    .box:media(min-width: 1200px) {
    width: 1000px;
    }

    View full-size slide

  124. .box {
    width: 1200px;
    }
    .box:media(min-width: 1200px) {
    width: 1000px;
    }
    And now,
    we're in a loop...

    View full-size slide

  125. https://css-tricks.com/selectors-that-depend-on-layout/

    View full-size slide

  126. Checking for an
    existing class

    View full-size slide

  127. const elem = querySelector('.component');
    if(
    elem.classList.contains('is-active') &&
    elem.classList.contains('is-awesome')
    ) { /* ... */ }

    View full-size slide

  128. const elem = querySelector('.component');
    if(
    elem.matches('.is-active') &&
    elem.matches('.is-awesome')
    ) { /* ... */ }

    View full-size slide

  129. const elem = querySelector('.component');
    if(elem.matches('.is-active.is-awesome')) {
    /* ... */
    }

    View full-size slide


  130. The Element.matches()
    method returns true if the
    element would be selected by
    the specified selector string;
    otherwise, returns false.

    View full-size slide


  131. The Element.matches()
    method returns true if the
    element would be selected by
    the specified selector string;
    otherwise, returns false.

    View full-size slide

  132. background-repeat
    has other options
    than repeat

    View full-size slide

  133. .box {
    background-image: url(https://.../jsunconf.svg);
    }

    View full-size slide

  134. .box {
    background-image: url(https://.../jsunconf.svg);
    background-repeat: repeat;
    }

    View full-size slide

  135. .box {
    background-image: url(https://.../jsunconf.svg);
    background-repeat: round;
    }

    View full-size slide

  136. .box {
    background-image: url(https://.../jsunconf.svg);
    background-repeat: space;
    }

    View full-size slide

  137. min-content/
    max-content

    View full-size slide

  138. Merel van der
    Woude
    Creative director bij Butterfly Works

    View full-size slide

  139. Merel
    van der
    Woude
    Creative director

    View full-size slide

  140. Merel van der Woude
    Creative director, overall great person, loves books

    View full-size slide

  141. Merel van der Woude
    Creative director, overall great person, loves books

    View full-size slide

  142. Merel van der Woude
    Creative director, overall great person, loves books
    That's not
    possible, is it?

    View full-size slide


  143. Merel van der Woude
    Creative director

    View full-size slide


  144. Merel van der Woude
    Creative director

    h2 {
    width: min-content;
    min-width: 0;
    max-width: 100%;
    }

    View full-size slide


  145. Merel van der Woude
    Creative director

    h2 {
    width: min-content;
    min-width: 0;
    max-width: 100%;
    }
    h2 span {
    width: max-content;
    max-width: 100%;
    }

    View full-size slide

  146. https://codepen.io/maddesigns/pen/YNXvMz

    View full-size slide

  147. Dry package
    configuration

    View full-size slide

  148. {
    "name": "my-package",
    "scripts": {
    "lint": "eslint ./src/*",
    "test": "jest ./src/*"
    }
    }

    View full-size slide

  149. {
    "name": "my-package",
    "config": {
    "src": "./src/*"
    },
    "scripts": {
    "lint": "eslint $npm_package_config_src",
    "test": "jest $npm_package_config_src"
    }
    }

    View full-size slide

  150. {
    "name": "my-package",
    "config": {
    "src": "./src/*"
    },
    "scripts": {
    "lint": "eslint $npm_package_config_src",
    "test": "jest $npm_package_config_src"
    }
    }
    Avoid duplication

    View full-size slide

  151. {
    "foo": "bar"
    "scripts": {
    "start": "node index.js"
    }
    }

    View full-size slide

  152. {
    "foo": "bar"
    "scripts": {
    "start": "node index.js"
    }
    }
    // index.js
    console.log(process.env.npm_package_foo);
    // 'bar'

    View full-size slide

  153. And finally...

    View full-size slide

  154. function f() {
    try {
    return 'A';
    } finally {
    return 'B';
    }
    }
    f(); // ?
    'B'

    View full-size slide

  155. function g() {
    try {
    throw new Error('Foo');
    } catch( e ) {
    return 'A';
    } finally {
    return 'B';
    }
    }
    f(); // ? 'B'

    View full-size slide

  156. function h() {
    try {
    throw new Error('Foo');
    } finally {
    return 'B';
    }
    }
    h(); //? 'B'
    (without throwing exception)

    View full-size slide

  157. function i() {
    try {
    throw new Error('Foo');
    } catch( e ) {
    throw new Error('Bar');
    return 'A';
    } finally {
    return 'B';
    }
    }
    i(); //?
    'B'
    (without throwing exception)

    View full-size slide


  158. If the finally block returns a value,
    this value becomes the return value
    of the entire try-catch-finally
    production, regardless of any return
    statements in the try and catch
    blocks.

    View full-size slide


  159. If the finally block returns a value,
    this value becomes the return value
    of the entire try-catch-finally
    production, regardless of any return
    statements in the try and catch
    blocks.

    View full-size slide

  160. 77 documented
    learnings

    View full-size slide

  161. www.stefanjudis.com/today-i-learned

    View full-size slide

  162. It only takes 

    10 minutes

    View full-size slide

  163. Did I improve? Like, at all?
    Oh yes!!!

    View full-size slide

  164. I'm building my own
    knowledge base!

    View full-size slide

  165. Celebrate learnings!

    View full-size slide

  166. Huh!

    I didn't know that!

    View full-size slide

  167. THANKS
    FOR LISTENING!
    @stefanjudis
    www.stefanjudis.com
    my-links.online/i-didnt-know

    View full-size slide

  168. THANKS
    FOR LISTENING!
    @stefanjudis
    www.stefanjudis.com
    my-links.online/i-didnt-know
    Yes, I bought
    my-links.online

    View full-size slide

  169. THANKS
    FOR LISTENING!
    @stefanjudis
    www.stefanjudis.com
    my-links.online/i-didnt-know

    View full-size slide