收集一些前端的防御性编程技巧

什么是防御性编程?

一个页面在呈现给用户之前需要经过静态资源加载、后端接口请求和渲染这三个过程,我们要做的就是在各个过程中防御可能出现的异常情况,保持流畅的用户体验,同时还要应对来自外部的攻击。

关于对象的操作

  • 可选链操作符(?.) 简化 判断对象是否为null

    如果可选链 ?. 前面的值为 undefined 或者 null,它会停止运算并返回 undefined

    可选链 ?. 不是一个运算符,而是一个特殊的语法结构

    • ?.() 用于调用一个可能不存在的函数。

    • 可选链 ?. 不能用在赋值语句的左侧

    let value = obj.first && obj.first.second;
    // 等于 ==》
    let value = obj.first?.second;
    
  • 空值合并操作符??, 可以在使用可选链时设置一个默认值:

    let customerCity = customer?.city ?? "暗之城";
    

    如果第一个参数不是 null/undefined,则 ?? 返回第一个参数。否则,返回第二个参数。

    使用场景:

    • 可以使用 ?? 序列从一系列的值中选择出第一个非 null/undefined 的值。

    • 默认值赋值

    • || 返回第一个 值。

    • ?? 返回第一个 已定义的 值。

    • 如果没有明确添加括号,不能将其与 ||&& 一起使用

  • 使用解构赋值时,注意对象是否为undefined,尤其是嵌套的子对象,如果属性不存在为undefined,就会报错。
    可以使用 ||运算符:

// 使用
const {aa, bb} = obj || {} 
  • 解构默认值仅在 undefined 的情况下生效,null、false、0 不生效。

数组操作方面

  • 取数组的最后一个元素:
    除了用长度arr[arr.length-1]

    还可以: arr.slice(-1)

  • 当使用数组的方法时候,为了避免报undefined的错误,所以需要判断一下 再取值操作:
    arr && arr?.length > 0
    (有时候后端返回null,如果直接当成数组去调用map、filter、forEach 等方法时,页面会报undefined的错,从undefined读取属性就会导致这个错误(同理,null也一样)

  • 利用数组方法巧妙去重

const arr1=[1,3,4,5,6,7,5,4,3]
const arr2 = arr1.filter((item,index)=>{
	return arr1.indexOf(item) === index;
})
console.log(arr2)

注意: 对象的数组中查找对象,indexOf() 方法会在查找时比较引用而不是。这意味着它会检查对象是否完全相同,而不是检查对象的属性值是否相同。

const array = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
    { id: 3, name: 'Charlie' }
  ];
  
 const obj = { id: 2, name: 'Bob' };
 
 console.log(array.indexOf(obj)); // 输出: -1,因为这是一个新的对象,与数组中的对象不是同一个引用
 
 console.log(array.indexOf(array[1])) // 输出: 1

在这样的情况下,可能需要使用 findIndex()

findIndex() : 第一个参数为比较函数,多用于非基本类型(例如对象)的数组索引查找,或比较复杂的查找条件

计算精度损失问题

由于JS的运算机制存在精度损失,导致 0.1+0.2 != 0.3

原因:计算机是二进制运算的,有限十进制小数 0.1 转化成了无限二进制小数 0.00011001100…,可以看到精度在转化过程中丢失了

解决方法:不要直接使用 运算符号进行加减, 可以引入插件:

npm install mathjs

封装:

import * as math from 'mathjs';
export default {
    // 加
	add(num1,num2){
		return math.add(math.bignumber(num1),math.bignumber(num2));
	},
	// 乘
	multiply(num1,num2){
		return math.multiply(math.bignumber(num1),math.bignumber(num2));
	},
	// 减
	subtract(num1,num2){
		return math.subtract(math.bignumber(num1),math.bignumber(num2));
	},
	// 除
	divide(num1,num2){
		return math.divide(math.bignumber(num1),math.bignumber(num2));
	}
}

使用:

import math from './math.js'
let addNum = math.add(3,2); // 5
let mulNum = math.multiply(3,2); // 6
let subNum = math.subtract(3,2); // 1 
let divNum = math.divide(3,2); // 1.5

参考: https://juejin.cn/post/6980282248104771615

计算百分比时,为了精度,通常做法是,除法之后先乘法再除法:cnt/total *10000/100

超大number 精度丢失问题

前端大数字之间的运算,精度丢失问题无法解决;

因为number的基本类型不能超过2^53,不然就会精度丢失
为了解决这个限制,在ECMAScript标准中出现了BigInt

BigInt可以表示任意大的整数;

前端的大数据,可以在第一步就先给大数据后加n,直接写成BigInt类型的就可以;

let result=124569875984123677888999n; 
String(result);

接口错误捕获

虽然后端接口定义了返回值的类型和结构,但是也有可能存在接口异常,不按规定的结构返回的情况,这时候前端要注意代码中使用接口中值的情况,避免页面异常。

部分 UI 的 JavaScript 错误不应该导致整个应用崩溃,为了解决这个问题,React 16 引入了一个新的概念 —— 错误边界。

错误边界是一种 React 组件,这种组件可以捕获并打印发生在其子组件树任何位置的 JavaScript 错误,并且,它会渲染出备用 UI,而不是渲染那些崩溃了的子组件树。错误边界在渲染期间、生命周期方法和整个组件树的构造函数中捕获错误。

  • 对于接口无数据、数据异常等情况、前端要做兼容处理。

  • 页面做到可降级

对于一些刚上新的业务,或者有存在风险的业务模块,或者会调取不受信任的接口,例如第三方的接口,这个时候就要做一层降级处理,例如接口调用失败后,剔除对应模块的展示,让用户无感知的使用

页面状态感知-交互

  • 巧用loading和disabled
    用户操作后,要及时loading和disabled确保不让用户进行重复,防止业务侧出现bug

  • 无网络的情况下,策略是什么。以及弱网情况下,策略是什么,等待加载 or 交互提示。
    参考:https://blog.csdn.net/qq_43203586/article/details/120491359

  • 文本过长溢出——省略号

.ellipsis{
overflow: hiden;
text-overflow: ellipsis;
white-space: nowrap;
}
  • 善用 max-width \ min-width的使用,防止样式因窗口大小而变形
  • 必要时显示滚动条,overflow: auto

参考:
https://blog.csdn.net/weixin_40906515/article/details/115364712

npm run build后如何本地运行build后的目录

在这里插入图片描述

全局安装本地服务器依赖

npm install serve -g

将指定目录作为本地服务器根目录启动服务

# 将当前目录下的dist文件夹作为应用根目录,并指定服务端口为5000
serve dist -p 5000

前端打包上线后,用户端的浏览器没有刷新缓存

原因:浏览器的缓存策略,这里需要知道浏览器有两种缓存模式:强缓存和协商缓存。

  • 强缓存:

需要修改nginx配置信息

参考:

https://blog.csdn.net/y523006369/article/details/103614312

在这里插入图片描述

在这里插入图片描述

  • 15
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值