Record

asset references

ref -> reference

该 tc39 的提议中提议实现一种语法来引入asset类型文件
get first class references to a module identity without actually loading or initializing that module
That “asset” could be another ECMAScript module. Unlike import, the asset statement doesn’t actually load the other module. It’s just a reference to it. This reference can be passed to any dynamic import call to actually load it and asynchronously resolve it to a module instance.
只做引用,不做使用

  1. async function Bar() {
  2. let foo = await import(Foo);
  3. }

关于用 import 语法来引入 asset 类文件一直很让人困惑,因为 asset 的加载以及处理方式明显跟 js 类文件是完全不同的,问题在于 es 的语法暂无法区分,所以使用了 import 语法。
其他工作则由 webpack 来处理了,无论是将import 转为返回 url string,还是转为 base64。
通过类似这样的额外语法,可以让 asset 类文件的引入更清晰,而且这样的引入就是单纯的引入,后续的如何转化,如何处理,则交由使用者来进行。
https://github.com/tc39/proposal-asset-references

如何了解es最新提案

https://juejin.cn/post/6844904030838194189#heading-5

First Class 的概念

https://developer.mozilla.org/zh-CN/docs/Glossary/First-class_Function
First Class: 该类型的值可以作为函数的参数和返回值,也可以赋给变量。
Second Class: 该类型的值可以作为函数的参数,但不能从函数返回,也不能赋给变量。
Third Class: 该类型的值作为函数参数也不行
多数程序语言中的整型、字符类型都是First Class的。

断点调试

DOM breakpoint

在 Elements 面板,右键点击节点唤出菜单,添加对应的 DOM 断点,可以监测指定节点的子树修改、属性修改、以及节点的移除。
21.05.27 - 图1

Source breakpoint

无需在源码中添加 debugger。直接在 Source 面板添加断点即可调试。见下图行号上的小蓝色箭头!

21.05.27 - 图2

Conditional breakpoint

条件断点。只有符合条件时,才会触发断点
21.05.27 - 图3

21.05.27 - 图4

21.05.27 - 图5

除此之外,还有 blackbox、XHR(fetch) breakpoint 等各种 Chrome 提供的工具

TypeScript

index signature

  1. type OnlyBoolsAndHorses = {
  2. [key: string]: boolean | Horse;
  3. };

https://github.com/Microsoft/TypeScript/issues/24220
目前的 索引签名还是有所限制的,如不能是一个 union,得用 key in 代替:
这种写法叫 mapped type

  1. type OptionsFlags<Type> = {
  2. [Property in keyof Type]: boolean;
  3. };

目前正在优化中:https://github.com/microsoft/TypeScript/pull/26797
完成后可以拥有更加自由的 index 类型写法。

ts 需求计划表

https://github.com/microsoft/TypeScript/wiki/Roadmap#43-may-2021

React

render-props用hook代替

如果render-props调用相当于传递一个函数 children,加计算衍生props,完全可以将计算用 props 传递给 useXX function 再调用 children 来实现。

  1. const Toggle = ({children, ...props}) => children(useToggle(props))

render-props的不可替代的用处是 让 子组件 自行选择使用复用块(inversion of control 的内容。且这样的选用过程是可以出现在一个独立的函数scope中的,相比 hooks 需要侵占组件 scope 的空间,实际会看上去舒服点。
原先的逻辑复用,尤其是 props衍生和独立状态管理 的复用部分已经完全可以被hooks所取代了。

children 不变,则 children 不会重渲染

该优化方式与将 JSX 通过 props 传递是一样的意思,可以作为后期优化点,前期未出现性能问题时,实无需关注。
如果 ExpensiveTree 未使用 memo包裹,每次set后的 rerender,都会导致无效渲染:

  1. function ExpensiveTree() {
  2. console.log('render')
  3. let now = performance.now();
  4. while (performance.now() - now < 100) {
  5. // Artificial delay -- do nothing for 100ms
  6. }
  7. return <p>I am a very slow component tree.</p>;
  8. }
  9. export default function App() {
  10. let [color, setColor] = useState('red');
  11. return (
  12. <div style={{ color }}>
  13. <input value={color} onChange={(e) => setColor(e.target.value)} />
  14. <p>Hello, world!</p>
  15. <ExpensiveTree />
  16. </div>
  17. );
  18. }

但如果把不需要使用到 color 这个状态的内容放到 childern 中,set 后的 rerender 在 ColorPicker 中发生,children 返回的 JSX 未做变化,children 则不会被重新渲染:

  1. function ColorPicker({ children }) {
  2. let [color, setColor] = useState("red");
  3. return (
  4. <div style={{ color }}>
  5. <input value={color} onChange={(e) => setColor(e.target.value)} />
  6. {children}
  7. </div>
  8. );
  9. }
  10. export default function App() {
  11. return (
  12. <ColorPicker>
  13. <p>Hello, world!</p>
  14. <ExpensiveTree />
  15. </ColorPicker>
  16. );
  17. }

但这个优化点会被 render-props 打破,因为childern() 的调用,必然导致 children 内的内容重新渲染。所以最简单的方式还是都先用 memo 包,至少不会有问题。

  1. export default function App() {
  2. return (
  3. <ColorPicker>
  4. {() => {
  5. return (
  6. <>
  7. <p>Hello, world!</p>
  8. <ExpensiveTree />
  9. </>
  10. )
  11. }}
  12. </ColorPicker>
  13. );
  14. }
  15. function ColorPicker({ children }) {
  16. let [color, setColor] = useState("red");
  17. return (
  18. <div style={{ color }}>
  19. <input value={color} onChange={(e) => setColor(e.target.value)} />
  20. {children()}
  21. </div>
  22. );
  23. }
  24. function ExpensiveTree() {
  25. console.log('render')
  26. let now = performance.now();
  27. while (performance.now() - now < 100) {
  28. // Artificial delay -- do nothing for 100ms
  29. }
  30. return <p>I am a very slow component tree.</p>;
  31. }