likes
comments
collection
share

写了将近一年的Web,总结一些收获到的知识点

作者站长头像
站长
· 阅读数 3

差不多一年前,由于移动端业务量逐渐下降,公司决定让我们这些android,ios的老兵们开始逐步介入web端的开发工作当中去,所以经过一段时间的学习,培训,小demo的练手,以及后来若干个大小项目的锻炼,个人也是慢慢的从一个懵懂的啥也不会的小卡拉米,变成了一个略微懂一些的大卡拉米,现在回想一下,在每一次项目中,自己也是或多或少都得到了一些成长,学到了一些东西,也正是因为目前处于成长学习阶段,由于基础不扎实,根基不稳,学到的东西如果不巩固的话,可能过一段时间就彻底忘了,下次遇到相同的问题还是不会,所以想借此机会总结复习一下,将这些知识点写下来加深记忆,可能这些东西在大多数大佬眼中都不值一提,包括我现在在写的时候也会下意识的想一想这么简单的东西是不是真的要写,但是,不能否认的是,所有内容都是当初通过查询资料,请教公司大佬等途径后,经历了一个“这可咋整啊”到“原来是这样”的过程,所以还是有必要写一下这个总结,加深一下对这些知识的掌握程度,本篇文章涉及到的内容有

  • 如何判断类型
  • 如何合并数组
  • 如何将数组中的所有元素用分隔符合并成一个字符串
  • 如何取两个数组的交集
  • 如何改变一个对象数组中所有元素的某个属性值
  • 如何将一个Map转换为json字符串
  • 如何防止频繁发送请求
  • 如何在Table底部新增一行展示额外数据

如何判断类型

typeof

由于TypeScript中有一个联合类型的概念在里头,让你不得不面对一些变量它有可能既可以是个number也可以是个string或者别的什么东西,所以在某一些需要针对不同类型的变量需要不同处理逻辑的场景中,就要判断下当前得到的变量值究竟属于什么类型,这里就要用到typeof运算符,来看个例子

写了将近一年的Web,总结一些收获到的知识点

这是一个判断入参是什么类型的函数,参数x是一个联合类型,最终函数需要根据实际不同的传参类型来输出不同的内容,这里就使用了typeof运算符,判断x是否为一个string类型的值,是就输出${x} is string,不是就输出${x} is number,调用一下函数后,得到结果如下

写了将近一年的Web,总结一些收获到的知识点

typeof可以判断的类型有以下几个"string","number", "bigint" , "boolean" ,"symbol" , "undefined" ,"object" ,"function"

instanceof

但是还有一些类型的数据,我们就不能用typeof来判断了,比如下面这个例子

写了将近一年的Web,总结一些收获到的知识点

这里定义了一个interface,命名为AAA,并且创建了两个class分别实现了AAA,那么如果我要在judgeType2函数里面要根据aaa的不同类型来执行不同的逻辑,那么该怎么判断呢,这里就要使用另一个操作符instanceof,用法同Java里面的instanceof基本一致,代码如下

写了将近一年的Web,总结一些收获到的知识点

再来测试一下这段代码的正确性,分别执行两次judgeType2,传参类型分别为OneAAATwoAAA,再去看下控制台的日志

写了将近一年的Web,总结一些收获到的知识点 写了将近一年的Web,总结一些收获到的知识点

显然结果符合我们的预期

如何合并数组

经常有这么个场景,需要将两组数据或者若干组数据组合在一起再发送给服务端,比如服务端需要一个字段,但是这个字段的数据是要从两个组件里面分别取出来拼在一起,那么这里就牵扯到如何合并数组的问题了,看下面这个例子

写了将近一年的Web,总结一些收获到的知识点

有两个数组arr1arr2,还有一个空的数组arr3,现在需要将arr1arr2的所有元素都放进arr3里面,那么有三种做法可以实现

第一种:遍历数组

写了将近一年的Web,总结一些收获到的知识点

arr1arr2分别调用forEach函数,遍历整个数组,将遍历到的元素pusharr3里面,这样就能实现合并数组的目的

第二种:使用concat

第一种方法虽然可以达到目的,但是略微有些繁琐,我们还有更加简单的办法,就是使用concat函数 写了将近一年的Web,总结一些收获到的知识点

concat函数是将两个数组连在一起,达到合并数组的目的,从代码上看,这种方式要比第一种简洁,而且也更加的直观,再来看第三种方法

第三种:扩展运算符...

这里直接使用扩展运算符...来实现,看代码

写了将近一年的Web,总结一些收获到的知识点

不需要遍历,也不需要使用什么函数,直接将两个数组像元素一样塞到arr3里面,前提当然是arr1arr2要使用运算符...,这个运算符也是在实际开发过程中比较常用的

三种方法最终的执行结果是一样的

写了将近一年的Web,总结一些收获到的知识点

如何将数组中的所有元素用分隔符合并成一个字符串

众所周知,每个服务端写的接口都不太一样,除了一些有明确代码规范的例外,大多数情况经常会遇到原始数据比如说是个数组,当作为参数传给服务端的时候,有些服务端可能不需要你做任何处理拿到什么就给他什么就好,而有些服务端由于代码结构,架构设计,数据库等一些原因,需要你将数据在处理一下再给他,遇到这种情况,我们也应当具备处理这些问题的能力,举个例子,你有一个数组,当上报给服务端的时候,需要将这个数组中的元素拼接成一个字符串,元素之间用某个符号隔开,那该怎么做呢?看代码

写了将近一年的Web,总结一些收获到的知识点

当你不知道join这个函数的时候,你可能会傻傻的去遍历整个数组,然后在每次遍历到一个元素的时候,在末尾添加一个分隔符,最终还要在得到的字符串中,去除最后一个分隔符,非常繁琐,但是使用join函数就不一样了,仅仅一行代码就完成了这个功能,我们看下执行combineWith函数后的结果

写了将近一年的Web,总结一些收获到的知识点

如何取两个数组的交集

这个问题来源于一个真实事件,有次在渲染一个穿梭框的时候,发现在穿梭框右边的元素无法选中移动到左边了,测试火急火燎的跑来问我咋回事,之前还好好的啊,我查了半天才发现是接口数据里面,穿梭框右边的数据对应的数组中,存在着一些脏数据,也就是之前操作过的数据后来从数据库中删除了,但是接口仍旧将这些数据的id返回过来,那么找后端改呗,但是后端告诉我改不了,巴拉巴拉一堆原因,怼了一会最终我还是自己处理吧不浪费时间了,方案就是将穿梭框右边的数据对应数组同总的实际数据做下对比,取下交集就是实际应当拿来渲染的数据,那么这里就是一个数组之间如何取交集的问题,看下例子

写了将近一年的Web,总结一些收获到的知识点

同样有两个数组arr1arr2,我们可以看到这俩数组中存在着共同的元素,那么如何将这个共同的元素找出来呢,我们看下第一种做法

方法一

写了将近一年的Web,总结一些收获到的知识点

可以看到这里用到了filter函数,对arr1里面的数据做一次过滤,咋过滤呢?就是将arr1里面的元素找出来,如果这些元素在arr2里面也存在的话,那么这些元素就是我们需要的,执行一遍pickSame函数后看下结果

写了将近一年的Web,总结一些收获到的知识点

结果正如我们预期的一样,将共同元素找出来了,在看下第二种方法

方法二

写了将近一年的Web,总结一些收获到的知识点

这里同样也是对arr1先做次过滤,但是filter内部却不一样了,里面用到了some函数,some函数是干什么用的呢?和filter函数有点像的是,some内部同样也是接收一个条件语句,但不同的是some的返回值是一个Boolean,当arr1的元素与arr2的元素相同的时候才返回true,不同就返回false,那么当返回true的时候,item就是我们需要的共同元素,这里就不执行了,结果都是一样的

如何改变一个对象数组中所有元素的某个属性值

这是在一次对列表数据做批量更新状态时候遇到的一个问题,我这边举个同样的例子,比如这里有一个员工的接口Employee,这个接口里面声明了如下几个属性

写了将近一年的Web,总结一些收获到的知识点

然后再创建一个员工的数组,随便在数组中加几个员工进去

写了将近一年的Web,总结一些收获到的知识点

现在我想要将这三个员工的职级level都改为5,那么最方便的做法就是使用map函数,代码如下

写了将近一年的Web,总结一些收获到的知识点

非常简单,在map函数内将元素的level属性赋值为5就好了,打印出来的结果也是正确的

写了将近一年的Web,总结一些收获到的知识点

但是这样做的话就有个问题,我们employees数组里面的内容都改变了,如果有些场景里面我们还需要用到这些原数据,那么这种方式显然是不可取的,但是既要保留原数据,又要更改数据里面的元素值,该怎么做呢?我们可以用下面这种方式

写了将近一年的Web,总结一些收获到的知识点

不是直接在原数据上映射,而是复制了一份数据出来,在新数据上做映射操作,这种做法会返回一个新的数组,我们命名为turnedArr,而原来的数组employees保持不变,为了验证正确性,我们将两个数组都打印出来看下结果

写了将近一年的Web,总结一些收获到的知识点

显然我们得到了想要的结果

如何将一个Map转换为json字符串

JSON将一个对象转换为json字符串,或者将json字符串转换为对象的操作,基本每个项目里面都会用到,这些基本都属于常规操作了,就连我这样的新手小菜鸟都快用麻了,但就是这么个简单的操作依然也会给我带来小惊喜,比如有一次在操作一个Map的时候,在最终保存上报给服务端前我想打印看看数据对不对,由于上报给服务端肯定是要用string类型的,所以打印的时候就JSON.stringify了一下,类似代码如下

写了将近一年的Web,总结一些收获到的知识点

老手肯定一眼就看出来了问题,但是对于我这样的新手却是一点也没发现,结果打印日志上啥数据也没有

写了将近一年的Web,总结一些收获到的知识点

后来又试了几次依然还是不行,开始我以为是stringify的一个bug,问了一下公司的前端大佬才知道是为啥,stringify并不是什么类型都可以转,像是对象,数组,字符串,数值,布尔值这些都是可以转成json字符串的,但唯独Map不行,所以如果想要将一个Map结构的数据转成json字符串,必须先将Map转换成stringify可以转的类型,正确的做法如下所示

写了将近一年的Web,总结一些收获到的知识点

使用Object.fromEntriesMap转成一个object,这样就可以使用stringify转换成json字符串了,执行printMap函数后结果如下

写了将近一年的Web,总结一些收获到的知识点

如何防止频繁发送请求

Web开发最常见的就是查询列表,点击查询按钮后将数据展示在列表上,但要知道每一次查询对于后端来讲就是一次数据库的查询操作,遇到一些老项目大项目,数据量比较庞大的时候,查询操作是非常耗时耗资源的,所以为了防止频繁点击查询按钮发送请求,我们需要在按钮点击上做一些处理,达到的效果就是无论点击多少次按钮,发送请求的次数都是可控的,目前最常用的方式有两个,一个是防抖(debounce),一个是节流(throttle)

安装lodash插件

防抖与节流都是在lodash库里面,所以如果项目中没有lodash,需要先安装一下,命令如下

写了将近一年的Web,总结一些收获到的知识点

安装完了以后导入debouncethrottle函数

写了将近一年的Web,总结一些收获到的知识点

防抖(debounce)

首先尝试下防抖函数,我们先在页面上创建个按钮,然后在按钮的点击事件里面打印一行日志

写了将近一年的Web,总结一些收获到的知识点

目前这样写的话,反复点击按钮,控制台会不断输出日志,按几次就出来几条

写了将近一年的Web,总结一些收获到的知识点

如果将打印日志换成向服务端发送请求,那么这短短的时间内服务端就接收了多次同样的请求,显然这样做是不合理的,现在我们如果在点击事件内加入防抖处理,结果会如何呢

写了将近一年的Web,总结一些收获到的知识点

debounce函数的参数有很多,我们主要用前两个参数,第一个接收的是个函数,第二个接收的是个时间,单位是毫秒,这个时间的意思是延迟一段时间后执行函数,比如我们这里设置的是1000毫秒,那么无论我们点击多少次按钮,它只会在最后一次点击后经过1000毫秒才会执行点击事件,我们看下

写了将近一年的Web,总结一些收获到的知识点

我们看到控制台上最终就输出了一条日志,该日志就是在最后一次点击后过了1000毫秒才输出的,这个就是防抖

节流(throttle)

节流与防抖刚好相反,这个相反体现在哪呢?之前防抖是在最后一次点击后经过若干时间才执行函数,而节流是第一次点击按钮后就会输出日志,但是后面无论点击多少次都不会再输出日志,直到经过了设置的延迟时间后,才会再一次通过点击输出日志,我们将上述代码改一下

写了将近一年的Web,总结一些收获到的知识点

代码上没多大区别,只是将debounce换成了throttle,会达到什么效果呢?我们看下

写了将近一年的Web,总结一些收获到的知识点

我们看到这次不用等停止点击后才打印出日志,每条日志都是间隔着1000毫秒后才打印出来,这个就是节流与防抖的区别

如何在Table底部新增一行展示额外数据

Table用的场景还是蛮多的,用来展示列表数据,一般性接到需求里面带有这种列表页面的一定很开心,因为基本跟白给的一样,拿到数据以后填到datasource属性里面去就好,但是如果要让你在Table底部新增一行用来展示一些非数据源的数据,那还开心的起来吗?比如有这么个需求,需要统计去年小赵,小钱,小孙,小李四个人每个季度所做的需求数量,并且找出需求做的最多的那个人,所有数据都必须展示在Table里面,那么该怎么做呢?首先来把数据创建出来

写了将近一年的Web,总结一些收获到的知识点

创建了一个数据类Brick,然后模拟了几条Brick的数据,接着就是列表的TableColumnsType,整个列表就可以渲染出来了

写了将近一年的Web,总结一些收获到的知识点 写了将近一年的Web,总结一些收获到的知识点

目前来讲都很顺利,但是接下来要再加一行显示每个季度做的需求最多的人,这个该怎么做呢?毕竟这个最后一行的数据结构同其他数据不一样,所以不能通过在数据源里面加数据的方式来做,那么只能手动写了,方式就是通过Table组件里面的summary属性,这个属性了里面我们使用Table.Summary组件来表示列表底部的额外内容,每一行Summary都是包在Table.Summary.Row里面,每一个单元格用Table.Summary.Cell来表示

写了将近一年的Web,总结一些收获到的知识点

index相当于每一个单元格的位置,那么0的位置可以写上这一行summary的描述,后面依次就是每个季度需求做的最多的人,接下来就是把需求做的最多的人计算出来填进去就好了,这部分的计算方式就是先将数据按照各个字段从大到小排序,然后去第一个元素的name

写了将近一年的Web,总结一些收获到的知识点

最后一步就是将计算出来的值代入到各个Cell里面就完工了

写了将近一年的Web,总结一些收获到的知识点

这就是给Table底部新增额外数据的方式,我们看下最终展示的效果

写了将近一年的Web,总结一些收获到的知识点

总结

差不多就这些了,能想到的基本都写上去了,可能有遗漏的东西后面想到了会补上,这篇文章相当于是一个学习笔记,内容都比较偏基础,没啥炫技的东西(毕竟也没好炫的),但是每个知识点都是在实际项目当中切身遇到并解决掉的,接下去接手项目会慢慢变复杂,奇奇怪怪的问题也会不断被接触到,我也会继续保持着将学到的东西都记下来,然后以这样笔记类型的文章分享出来