2023-05-23 02:18:10    10    0    0

测试网站

  • jsperf
  • jsfiddle
  • JSBench
    执行并比较不同 JavaScript 代码片段的执行速度。 通过简单而简短的 URL 与他人在线共享和协作。

合并

测试条件 Chrome版本94.0.4606.81 Firefox版本93.0 (64 位)
Object.assign对象合并 14.07080078125 ms 12.11 ms
展开运算符对象合并 18201.126953125 ms 7424.69 ms
展开运算符数组加单个 42.848876953125 ms 877.14 ms
push方法数组加单个 0.489013671875 ms 0.89 ms
concat方法数组加单个 0.6640625 ms 2.40 ms
展开运算符两个大数组合并 38.1337890625 ms 43.64 ms
concat方法两个大数组合并 4.3740234375 ms 31.28 ms

性能测试结论

在循环比较多或者操作的数组长度比较大的情况下:

  1. Object.assign 多数情况下性能比 展开运算符(...) 的性能高
  2. 数组自带的方法 connat、push 性能比 展开运算符(...) 的性能高

小结

Chrome版本94.0.4606.81Firefox版本93.0 (64 位) 的浏览器下

  • 对象合并,数组合并,Object.assign、connat 的性能会比 展开运算符“...” 的性能高
  • Object.assign 会触发 Proxy/Object.definedPropertyset 方法,展开运算符“...” 不会触发
  • Object.assign展开运算符 都是浅拷贝
  • 合并对象、数组的时候,展开运算符放在前面的性能比放在后面的性能高
  • 不定参数(function (a, ...b) {})的时候,有自己的使用方式
  • 在拷贝的情况下, 展开运算符“...”Object.assign 性能高
2023-04-17 11:30:32    25    0    0

getBoundingClientRect方法简介

getBoundingClientRect 返回的是一个 DOMRect 对象,是一组矩形集合,我们这次所使用的返回值主要是left、top、bottom和right。其余的返回值width、height、x、y这次用不到,就不再讨论。
使用方法如下:

  1. let domToTop = dom.getBoundingClientRect().top // dom 的顶边到视口顶部的距离
  2. let domToLeft = dom.getBoundingClientRect().left // dom 的左边到视口左边的距离
  3. let domToBottom = dom.getBoundingClientRect().bottom // dom 的底边到视口顶部的距离
  4. let domToRight = dom.getBoundingClientRect().right // dom 的右边到视口左边的距离

注意事项:

  1. 得到的值是相对于视口而言的,即如果页面的滚动位置发生变化,那么得到的top、left也会发生变化;如果需要计算到body边框的距离,需要再加上网页滚动条的长度。下面会给出完整例子。
    这个方法返回的四个值都是相对于当前视口的左上角而言的。即top和bottom是dom的顶边和底边到视口的顶部的距离,同理left和right是相对于视口左边的距离。
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <style>
  7. .box {
  8. width: 110%;
  9. height: 200%;
  10. position: absolute;
  11. top: 0;
  12. left: 0;
  13. border: 1px solid red;
  14. }
  15. .content {
  16. width: 20%;
2023-04-02 17:44:14    30    0    0

推荐以下两种手动保存状态的方式

  1. 将需要保存状态组件的state提升至父组件中保存。
  2. 使用 css visible 属性(display还是content-visibility ? )来控制需要保存状态组件的渲染,而不是使用 if/else ,避免React将其卸载。

目前市面上自动状态保存库主要从两方面下手:

  1. 改变路由机制,通常基于 React-Router 二次开发。React-Router 在路由切换时默认卸载非活动组件,因此这些库通过重写 React-Router 中的部分功能或者将其拓展的方式使得在路由切换时相关组件不被直接卸载,而是缓存下来。这种实现方式决定了状态保存的粒度只能具体到SPA的页面级别。
  2. 改变React组件被移除的方式。React在组件被移除时默认是被卸载的,这些库通过某些方式阻止或欺骗React使相关组件在移除时不被直接卸载,而是缓存下来。通过这种实现方式,状态保存的粒度可以精细到组件级别。
  3. React官方在一些关于 strict mode 的回复中提到了其正在开发的 <Offscreen> 组件,并且预计其在 react@18.X(非18早期版本)中可能会出现,其功能与vue <keep-alive> 类似。

根据对目前市场上存在的相关解决方案的调研,这里给出以下几点建议:

  • 如果项目中需要状态缓存处理的数据量较小,那最好还是按照React官方的建议,手动解决状态缓存问题。
  • 如果处理数据量较大,且缓存粒度为页面级别,那么推荐使用 react-router-cache-route
  • 如果处理数据量较大,且缓存粒度为组件级别,或者你的项目框架采用了umi(无法直接触及react-router),或者干脆没有使用react-router路由,那么推荐使用 react-activation 。此外umi中使用 react-activation 可以直接使用其封装插件 umi-plugin-keep-alive
2023-03-27 07:07:05    15    0    0
2023-03-27 06:21:21    13    0    0
2023-03-23 17:03:03    13    0    0
  1. 语言设置开启中文输入时使用英文标点
  2. 如1不行, 设置 -> 外观 -> 打开输入法工具栏 -> 点击工具栏标点符号来切换 -> 关闭输入法工具栏
2023-03-23 16:57:34    24    0    0

箭头函数在.tsx添加泛型报错

如:

  1. // a.tsx
  2. // 箭头函数添加泛型报错(Error: JSX element ‘T’ has no corresponding closing tag.ts(17008))
  3. const foo = <T>(props: T)=> void

原因: 因为泛型的语法与 JSX 的语法冲突,导致 TS 解析成 JSX 而产生 unexpected token 的问题

解决:
1. 不要写在 .tsx 文件里面就不会报错
2. 在后面加一个逗号就能正确解析了
3.

  1. const foo = <T,>(props: T)=> void
2023-03-21 17:04:57    32    0    0
2023-03-21 06:59:20    19    0    0

获得组件的props类型

React.ComponentProps<typeof Button>

TS内置类型

  1. ConstructorParameters :类构造函数参数类型的元组
  2. Exclude:将一个类型从另一个类型排除
  3. Extract:选择可分配给另一类型的子类型
  4. InstanceType:从一个新类构造函数中获得的实例类型
  5. NonNullable:从类型中排除空和未定义
  6. Parameters:函数的形参类型的元组
  7. Partial:使对象中的所有属性都是可选的
  8. Readonly:将对象中的所有属性设置为只读
  9. ReadonlyArray:创建给定类型的不可变数组
  10. Pick:对象类型的一种子类型,包含其键的子集
  11. Record:从键类型到值类型的映射
  12. Required:使对象中的所有属性都是必需的
  13. ReturnType:函数的返回类型
2023-03-20 16:58:27    9    0    0

any

当我们将某个变量定义为 any 类型后,TypeScript 将会跳过对这个变量的类型检查

unknown

TypeScript 在3.0版本引入了 unknown 类型,它可以理解为类型安全的 (type-safe)any

  • 任何类型都可以赋值给 unknown 类型的对象
  • unknown 类型的对象不可以直接赋值给其它非 unknownany 类型的对象,并且不可以访问上面的任何属性

never

never 就是 TypeScript 的底部类型

  • never 类型只接受 never 类型的对象, any 也不接受
  • never 会从联合类型中移除,类似于将零和其他数字相加时结果等于该数字。即 type Res = never | string // string
  • never 会覆盖交叉类型中的其他类型,类似于零乘其他数字时结果等于零。即 type Res = never & string // never

void

void 其实可以理解为 nullundefined 的联合类型,它表示空值

2/19