I didn't know that!

I didn't know that!

22725c2d3eb331146549bf0d5d3c050c?s=128

stefan judis

July 19, 2018
Tweet

Transcript

  1. @stefanjudis I didn't know that!

  2. My first job interview

  3. “ We're running a Magento shop combined with a CouchDB

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

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

    and a Frontend application with a Prototype/ jQuery mix.
  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...
  7. ... which lead to enormous stress.

  8. 8 years later

  9. The dangerous knowledge comparison

  10. What I think others know What I know

  11. Web Development

  12. None
  13. None
  14. You can't know everything!

  15. “ Don’t Compare Your Behind-The-Scenes With Everyone's Highlight Reel. by

    Tara Hunt
  16. None
  17. Know where to look for information

  18. The learning journey 
 won't end.

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

  20. None
  21. But then I learned it's deprecated...

  22. None
  23. Twitter is neither a bookmarking nor documentation tool!

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

  25. My learnings in 2 years (a random list in no

    particular order) (not always useful)
  26. NaNNaNNaN NaNNaN

  27. parseInt('Hello world', 10)

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

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

  30. isNaN(NaN); // true

  31. isNaN(NaN); // true isNaN(undefined); // true isNaN({}); // true isNaN(true);

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

    // false isNaN(null); // false isNaN(37); // false function myIsNaN(value) { return value !== value; }
  33. 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
  34. 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
  35. 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
  36. Object.is? === + SPECIAL HANDLING OF NaN, -0, +0

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

    Comparison
  38. ['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
  39. Abstract Equality Comparison Equality comparison and sameness == Strict Equality

    Comparison ===, indexOf, ... SameValueZero includes, ... SameValue Object.is, ...
  40. developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness

  41. Should I (force) push it?

  42. $ 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 ...
  43. $ git co -p --amend index.html $ git push -f

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

    origin some-feature It's very easy to overwrite remote changes with force pushing!
  45. None
  46. developer.atlassian.com/blog/2015/04/force-with-lease/

  47. Process substitution

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

  49. “ Process substitution allows a process’s input or output to

    be referred to using a filename.
  50. $ echo <(ls .) /dev/fd/11

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

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

  53. $ node <(pbpaste) foo

  54. $ node <(pbpaste) foo console.log("foo") But then I learned you

    can pipe into Node.js
  55. $ node <(pbpaste) foo

  56. $ pbpaste | node foo

  57. Break zooming with one line

  58. None
  59. body { font-size: 2vw; }

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

  62. None
  63. Stylesheets do not only block rendering

  64. <link rel="stylesheet" href="app.css" /> app.css START RENDER

  65. <link rel="stylesheet" href="app.css" /> <script> var script = document.createElement('script'); script.src

    = "analytics.js"; document.getElementsByTagName('head')[0].appendChild(script); </script>
  66. <link rel="stylesheet" href="app.css" /> <script> var script = document.createElement('script'); script.src

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


    
 <link rel="stylesheet" href="app.css" /> app.css analytics.js
  68. WAT!!!

  69. None
  70. { 'ü': 'foo', 'ü': 'bar', '': 'baz', '': 'wat!' }

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

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

  73. “ 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.
  74. “ 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.
  75. Unicode is powerful and very fascinating (and scary)

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

  77. None
  78. "Logical" string comparisons

  79. 'aBcD' === 'abcd'

  80. 'aBcD' === 'abcd' // false

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

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

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

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

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

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

    'Price 2€' > 'Price 1€' // true 'Price 20€' > 'Price 3€' // false
  87. localCompare 'aBcD'.localeCompare('abcd', undefined, { sensitivity: 'base' }) // 0 'ábcd'.localeCompare('abcd',

    undefined, { sensitivity: 'base' }) // 0
  88. localCompare a ≠ b, a = á, a = A

    'aBcD'.localeCompare('abcd', undefined, { sensitivity: 'base' }) // 0 'ábcd'.localeCompare('abcd', undefined, { sensitivity: 'base' }) // 0
  89. 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
  90. 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"
  91. How to center elements

  92. None
  93. .center { display: flex; align-items: center; justify-content: center; }

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

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

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

    { display: grid; place-items: center; } 2 declarations!
  97. None
  98. developer.mozilla.org/en-US/docs/Web/CSS/place-items place-items support

  99. Querying the DOM is not equal querying the DOM

  100. <ul> <li>foo</li> <li>bar</li> <li>baz</li> </ul> document.querySelectorAll('li'); // NodeList(3) [li, li,

    li]
  101. <ul> <li>foo</li> <li>bar</li> <li>baz</li> </ul> document.querySelectorAll('li'); // NodeList(3) [li, li,

    li] document.getElementsByTagName('li'); // HTMLCollection(3) [li, li, li]
  102. <ul> <li>foo</li> <li>bar</li> <li>baz</li> </ul> NodeList(3) HTMLCollection(3)

  103. <ul> <li>foo</li> <li>bar</li> <li>baz</li> <li>wat</li> </ul> NodeList(3) HTMLCollection(4)

  104. <ul> <li>foo</li> <li>bar</li> <li>baz</li> <li>wat</li> </ul> NodeList(3) HTMLCollection(4) There are

    live and static element collections
  105. document.querySelectorAll // static NodeList

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

  107. document.querySelectorAll // static NodeList element.childNodes // live NodeList element.children //

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

    (live) HTMLCollection document.getElementsByTagName // (live) HTMLCollection
  109. www.stefanjudis.com/blog/accessing-the-dom-is-not-equal-accessing-the-dom

  110. WAT!!! (part 2)

  111. <label for="foo">Fooo</label> <p>Some more information</p> <input id="foo"> #foo:hover { background:

    DeepSkyBlue; }
  112. None
  113. “ 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.
  114. “ 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.
  115. kizu.ru/en/blog/label-to-input/

  116. Regular expressions

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

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

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

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

    true
  121. github.com/tc39/proposal-regexp-dotall-flag

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

  123. const regex = /Jane.Smith/;

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

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

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

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

    ] There are non-capturing groups in JavaScript
  128. Why we won't have element queries

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

  130. None
  131. .mod img { display: block; margin: 0 auto; width: 100%;

    max-width: 250px; }
  132. .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; }
  133. None
  134. .box { width: 1200px; }

  135. .box { width: 1200px; }

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

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

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

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

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

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

    } And now, we're in a loop...
  142. https://css-tricks.com/selectors-that-depend-on-layout/

  143. Checking for an existing class

  144. <div class="component"></div>

  145. <div class="component is-active"></div>

  146. const elem = querySelector('.component'); if( elem.classList.contains('is-active') && elem.classList.contains('is-awesome') ) {

    /* ... */ } <div class="component is-active is-awesome"></div>
  147. const elem = querySelector('.component'); if( elem.matches('.is-active') && elem.matches('.is-awesome') ) {

    /* ... */ } <div class="component is-active is-awesome"></div>
  148. const elem = querySelector('.component'); if(elem.matches('.is-active.is-awesome')) { /* ... */ }

    <div class="component is-active is-awesome"></div>
  149. “ The Element.matches() method returns true if the element would

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

    be selected by the specified selector string; otherwise, returns false.
  151. background-repeat has other options than repeat

  152. .box { }

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

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

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

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

  157. min-content/ max-content

  158. Merel van der Woude Creative director bij Butterfly Works

  159. Merel van der Woude Creative director

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

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

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

    books That's not possible, is it?
  163. <h2> Merel van der Woude <span>Creative director</span> </h2>

  164. <h2> Merel van der Woude <span>Creative director</span> </h2> h2 {

    width: min-content; min-width: 0; max-width: 100%; }
  165. <h2> Merel van der Woude <span>Creative director</span> </h2> h2 {

    width: min-content; min-width: 0; max-width: 100%; } h2 span { width: max-content; max-width: 100%; }
  166. https://codepen.io/maddesigns/pen/YNXvMz

  167. Dry package configuration

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

    ./src/*" } }
  169. { "name": "my-package", "config": { "src": "./src/*" }, "scripts": {

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

    "lint": "eslint $npm_package_config_src", "test": "jest $npm_package_config_src" } } Avoid duplication
  171. { "foo": "bar" "scripts": { "start": "node index.js" } }

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

    // index.js console.log(process.env.npm_package_foo); // 'bar'
  173. And finally...

  174. function f() { try { return 'A'; } finally {

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

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

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

    e ) { throw new Error('Bar'); return 'A'; } finally { return 'B'; } } i(); //? 'B' (without throwing exception)
  178. “ 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.
  179. “ 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.
  180. 77 documented learnings

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

  182. It only takes 
 10 minutes

  183. None
  184. Did I improve? Like, at all? Oh yes!!!

  185. I'm building my own knowledge base!

  186. Celebrate learnings!

  187. Huh!
 I didn't know that!

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

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

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