• 提升前端开发质量的十点经验沉淀


    分享一下平常开发经常出现问题,增加代码质量的十个小点:

    记得错误处理

    特别是网络请求或者其他异步操作中,await 记得包裹 try catch,可以给用户一个友好提示,同时可以考虑 catch 中需要做什么兜底处理,必要时进行上传日志。

    1. try {
    2. this.loading = this.$loading({
    3. lock: true,
    4. text: '加载中...',
    5. spinner: 'el-icon-loading',
    6. background: 'rgba(0, 0, 0, 0.7)',
    7. });
    8. const info = await resDistributeService({ taskTicketId: this.id });
    9. ...
    10. } catch (e) {
    11. this.$message({
    12. type: 'error',
    13. message: e.msg || e.message || '失败',
    14. });
    15. } finally {
    16. this.loading.close();
    17. }

    可以结合 finally,处理 loading 等。

    数字 0 的校验

    前端经常使用 !v ,来判断 v 是不是有值。

    1. if(!v){
    2. return
    3. }
    4. doSomething()

    但如果 0v 的有效值 ,此时本该处理,但会提前结束,最终引发错误。此时需要显示的判断是否是 null 或者 undefined

    1. if(v === null || v=== undefined){
    2. return
    3. }
    4. doSomething()

    默认对象采用函数返回

    由于 js 中的对象是引用,因此赋默认值的时候最好通过函数,每次都返回一个新对象。

    bad:

    1. const defaultCondition = {
    2. name: '',
    3. conditionList: [
    4. {
    5. conditionCode: '',
    6. conditionValue: null,
    7. },
    8. ],
    9. }
    10. export default {
    11. data() {
    12. return {
    13. condition: {...defaultCondition},
    14. };
    15. },
    16. methods: {
    17. closeDialog() {
    18. this.condition = {...defaultCondition};
    19. this.configId = null;
    20. this.$refs.form.resetFields();
    21. },
    22. },
    23. };

    good:

    1. const getDefaultCondition = () => ({
    2. name: '',
    3. conditionList: [
    4. {
    5. conditionCode: '',
    6. conditionValue: null,
    7. },
    8. ],
    9. })
    10. export default {
    11. data() {
    12. return {
    13. condition: getDefaultCondition(),
    14. };
    15. },
    16. methods: {
    17. closeDialog() {
    18. this.condition = getDefaultCondition();
    19. this.configId = null;
    20. this.$refs.form.resetFields();
    21. },
    22. },
    23. };

    接口地址单独存放

    将接口的定义放到统一文件中,未来变动改动起来会比较方便,如果各个 url 都写死在页面中以后就很麻烦了。

    1. // service.js
    2. import request from 'utils/request';
    3. const service = new (request('/api/m/mallorder/exp/compensation/customer'))();
    4. export const listService = (params) => {
    5. return service.post('/queryRuleList', params);
    6. };
    7. export const listDataKey = 'ruleVOList';
    8. export const idKey = 'ruleId';
    9. export const dialogEnumService = () => {
    10. return service.get('/info');
    11. };
    12. export const saveService = (params) => {
    13. return service.post('/saveRule', params);
    14. };
    15. export const detailService = (params) => {
    16. return service.get('/detail', params);
    17. };

    此外,网络请求一般都会在 npm 包的基础上自己再包一层,一方面可以注入共用参数,另一方面可以对返回数据进行统一的错误处理。

    函数多参数采用对象

    如果定义一个函数需要 3 个以上的参数

    1. function(a,b,c,d){
    2. }

    此时可以考虑采用对象解构,改为

    1. function({a=1,b,c,d}={}){
    2. }

    好处是未来需要扩展参数的时候,不需要太担心其他地方调用时候传参是否会引起问题。

    当然,如果参数过多也需要思考一下当前函数是否承载了太多的功能,进行一下功能上的拆分。

    函数单一职责

    当我们已经定义了一个函数,比如去初始一些变量。

    1. function initOptions(){
    2. a = xxx
    3. b = xxx
    4. }

    此时我们需要做另一件无关的事 【A】,虽然它和 initOptions 调用的时机一致,但最好不要直接放到 initOptions 中,而是新建一个函数单独调用。

    不然未来如果其他地方也要调 initOptions,但此时可能并不需要做【A】这件事情就会引起 bug

    参数合法性判断

    由于 js 语言的灵活性,函数传入的参数很可能不符合预期,必要时我们需要进行判断并且进行兜底处理,不可完全信任调用方。

    团队合作中,该函数在未来极大可能会被其他人调用。

    1. function doSomeThing(params1, params2) {
    2. if(params1 === null){
    3. return;
    4. }
    5. if(params2){
    6. ...
    7. }
    8. // 再去做我们的事情
    9. }

    如果后边的流程强依赖于 params,我们可以直接 return,必要时也可以上报日志或者 throw Error

    整数的处理

    js 中没有整数类型,即 java 中的 intlong 这些,所有数字都遵循 IEEE 754 标准,即 java 中的 double 类型,详细的可参考 浮点数详解。

    可以精确表示的最大整数是 9007199254740991,共 16 位,超过这个数精度可能会丢失,对于新接口,可以问一下后端相应数字字段的最大值会是多少。

    对于浮点数的处理,除了众所周知的 0.1 + 0.2 === 0.3 的值为false 外,当我们对数字进行运算的时候也需要注意。

    常见的将 9.04 元转为 904 分:

    img

    我们需要对结果进行取整处理。

    img

    可选链

    可选链操作符,参考 MDN ,用的比较多。

    和后端定的数组或者对象,后端有时候返回来的很可能是 null 甚至没有该字段,因此前端可以用可选链操作符用于数组、对象、函数,防止出现错误直接阻断后续流程。

    1. let nestedProp = obj.first?.second; // 等效于 obj.first && obj.fisrt.second
    2. //后续流程

    但不要过度使用可选链,如果某些地方理论上不会出问题,比如 let test = obj.first?.second,如果 second 一定能取到,我们直接 let test = obj.first.second 即可。

    不然未来如果这里由于某种原因出了问题导致 obj.firstnull,但我们使用了可选链,所以 obj.first?.second 也不会报错,我们就永远不会知道这里出现问题了。

    当然也需要权衡下,不加可选链造成js Error 会不会影响业务逻辑。

    对象or数组引用

    修改或者使用对象、数组时,时刻切记它们为引用,一处修改会造成处处修改。

    以上的点应该算已经融入血液中了,平常开发和帮同事过 pr 的时候会格外注意,和业务逻辑没有关系,但可以提升代码质量。还有 Vue 一些常见的点也总结了一下,在语雀建了一个文档,未来有其他想法也会再更新一下,感兴趣的同学可以收藏一下,前端实践沉淀

  • 相关阅读:
    关于servlet提交响应后无法跳转
    如何调节电脑屏幕亮度?让你的眼睛更舒适!
    css的rotate3d实现炫酷的圆环转动动画
    NeRF OpenCV OpenGL COLMAP DeepVoxel坐标系朝向
    LeetCode热题100——哈希表
    热门Java开发工具IDEA入门指南——了解并学习IDE
    UVa1311/LA2666 Servers
    安防视频/视频汇聚平台EasyCVR使用onvif探测添加设备通道详细步骤来啦!
    关于 Object obj = new Object()
    【笔试强训选择题】Day43.习题(错题)解析
  • 原文地址:https://blog.csdn.net/qq_41328247/article/details/126701168