文章转自豆皮范儿——防御性编程
一个测试工程师走进一家酒吧,要了一杯啤酒;
一个测试工程师走进一家酒吧,要了一杯咖啡;
一个测试工程师走进一家酒吧,要了-1杯啤酒;
一个测试工程师走进一家酒吧,要了一份asdfQwer@24dg!&*(@;
一个测试工程师走进一家酒吧,什么也没要;
一个测试工程师走进一家酒吧,又走出去又进来又出去又进来又出去,最后在外面把老板打了一顿;
一个测试工程师走进一家酒吧,要了NaN杯Null;
一个测试工程师冲进一家酒吧,要了500吨啤酒;
一个测试工程师把酒吧拆了;
一个测试工程师化装成老板走进一家酒吧,要了500杯啤酒并且不付钱;
一万个测试工程师在酒吧门外呼啸而过;
测试工程师们满意地离开了酒吧。
然后一名顾客点了一份炒饭,酒吧炸了。
今天的主题就是 如何避免酒吧爆炸 防御性编程
防御性编程(Defensive programming)是防御式设计的一种具体体现,它是为了保证,对程序的不可预见的使用,不会造成程序功能上的损坏。 它可以被看作是为了减少或消除墨菲定律效力的想法。
保护我们的代码远离来自“外部”的无效数据,无论这个“外部”的概念被定位为什么。
以前端为例,大概包括以下方面
后端接口
字段变化、增减
数据结构变化
各种null
、undefined
之类的
网络环境造成的问题
用户输入和操作
输入预期之外的内容
非常规操作,如快速点击
非常规环境,如慢网速环境
空值
造成的相关问题Uncaught TypeError: Cannot read property 'b' of undefined Uncaught TypeError: fn is not a function
要时刻注意外部变量是否有值,下面是处理空值的几种方法
// 逻辑或(||)操作符,会在左操作数为 假值 时返回右侧操作数。 const newData = data || {} // 空值合并运算符(??) 是一个逻辑运算符。当左侧操作数为 null 或 undefined 时,其返回右侧的操作数。否则返回左侧的操作数。 const newDataAlt = data ?? {} console.log(data.id)
函数默认参数在没有值或undefined
被传入时使用默认形参
function divideBy(a, b = 1) { return a / b; } divideBy(10, 2); // 5 divideBy(5); // 5
null
或其他falsy值是被认为有值的?.
(Optional chaining)如果链条上的一个引用是nullish (null
或 undefined
),.
操作符会引起一个错误,?.
操作符取而代之的是会按照短路计算的方式返回一个undefined
。
if (this.props.data && this.props.data.list && this.props.data.list[0]) { console.log(this.props.data.list[0]) // blabla... } // 使用 optional chain if (this.props.data?.list?.[0]) { console.log(this.props.data.list[0]) // blabla... }
setTimeout、异步请求等非同步代码的callback,需要特别注意异步操作前后的状态变化
要注意dom元素是否一直存在,组件是否unmount,特别是有对canvas的操作的时候
每个异步操作过程中的状态,页面上要有相应的loading
初始化的loading
按钮点击(防重复点击)
网络较差的时候容易暴露loading相关的问题
Uncaught SyntaxError: Unexpected token } in JSON at position 13
处理json的时候,一般都要使用try catch捕捉错误
const json = '{"a":1,"b":2}'; let result; try { result = JSON.parse(json); } catch (e) { // handle error }
Uncaught SyntaxError: Invalid or unexpected token
this.someMethod
或者this.state.someState
的拼写错误,eslint无法查出来Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。
Cross-site request forgery(跨站请求伪造)简称CSRF 或者XSRF, 其原理是攻击者构造网站后台某个功能接口的请求地址,诱导用户去点击或者用特殊方法让该请求地址自动加载。攻击者盗用了你的身份,以你的名义发送恶意请求。
是不是防御式代码越多越好呢? No
要考虑好什么地方需要进行防御,然后因地制宜地调整进行防御式编程的优先级。
例如对于网络请求,一般是统一处理超时、鉴权、各种错误code,而不是在业务层个别处理
如项目内部使用的utils函数和公开发布的package,后者防御要求更高
字节跳动数据平台前端团队,在公司内负责大数据相关产品的研发。我们在前端技术上保持着非常强的热情,除了数据产品相关的研发外,在数据可视化、海量数据处理优化、web excel、WebIDE、私有化部署、工程工具都方面都有很多的探索和积累,有兴趣可以与我们联系。