写代码时易出现的问题
-
-
避免永远 pending 的 Promise
new Promise(function (resolve, reject) { KNB.getLocation({ success(location) { if (location.lat) { resolve(location) } // 如果 lat=0,会永远 pending } }) })new Promise(function (resolve, reject) { KNB.getLocation({ success(location) { if (location.lat) { resolve(location) } else { reject() } } }) }) -
避免价格计算(js 精度问题),直接用 js 进行四则运算会有精度问题,引起用户端展示异常
1.22 / 100 // = 0.012199999999999999 0.3 - 0.2 // = 0.09999999999999998 const finalPrice1 = price * 0.8 const finalPrice2 = priceA - priceB const finalPrice3 = result.priceA * 0.97正确做法:对于 C 端业务,让后端计算好,后端下发字符串,前端只展示、不计算。
-
JSON.parse要try catch
在前后端协作中,后端往往会返回一个序列化字符串,需要前端使用 JSON.parse 解析。而后端返回的内容不总是可靠的,建议前端同学 try catch 做好降级方案。 这是个常见问题,到综前端、金融服务前端、服体前端、点评前端均有 COE 案例,含 2 个 S9。 -
Vue 组件错误的默认值
//错误示例 export default { props: { // 这里 prop auditShowConfig 的默认值本意可能是一个空对象,而现在这里的写法实际返回一个 undefined. auditShowConfig: { type: Object, default: () => {} } } } //正确示例 export default { props: { auditShowConfig: { type: Object, default: () => ({}) } } }- 避免重新定义同名变量
//错误示例 export const fastSignIn = (param) => { const param = { ...param, source: 1 } }- 避免使用ts-ignore
// @ts-ignore lx.foo() 对于没有被 ts 检测到的方法或者属性,应去解决问题而不是使用 `ts-ignore`。 -
-
技巧类
-
//bad cosnt obj = {} cosnt b = obj.a && obj.a.b console.log(b) // undefined //good cosnt obj = {} cosnt b = obj?.a?.b console.log(b) // undefined -
//bad cosnt a = b === '1' ? true: false //good cosnt a = b === '1' -
// bad--->这个方式参数就必须按顺序传递 const getUserInfo =(name,age,sex,mobile,hobby)=> { // 函数逻辑 } // good const getUserInfo =(userInfo)=> { // 函数逻辑 const {name,age,sex,mobile,hobby} = userInfo } -
// bad const counter =(state=0,action)=>{ switch (action.type) { case 'ADD': return state + 1 case 'MINUS': return state - 1 default: return state } } // good const counter =(state=0,action)=>{ const step={ 'ADD':1, 'MINUS':-1 } return state + (step[action.type] ?? 0) } -
// bad const checkGameStatus =()=>{ if(status===0||(satuas===1&&isEnd===1)||(isEnd===2)){ // 调用 } } // good const isGaneOver =()=>{ return (status===0||(satuas===1&&isEnd===1)||(isEnd===2)) } const checkGameStatus =()=>{ if(isGameOver()){ // 调用 } } -
// bad const publishPost =(post)=>{ if(isLoggenIn){ if(post){ if(isPostValid()){ doPublishPost(post) }else{ throw new Error('文章不合法') } }else{ throw new Error('文章不能为空') } }else{ throw new Error('用户未登录') } } // good const publishPost =(post)=>{ if(!isLoggenIn){ throw new Error('用户未登录') } if(!post){ throw new Error('文章不能为空') } if(!isPostValid()){ throw new Error('文章不合法') } doPublishPost(post) } // bad const createElement =(item)=>{ if(item.type==='ball'){ cosnt div = document.createElement('div') div.className = 'ball' div.style.backgroundColor = item.color return div }else if(item.type==='block'){ const div = document.createElement('div') div.className = 'block' div.style.backgroundColor = item.color return div }else if(item.type==='square'){ const div = document.createElement('div') div.className = 'square' div.style.backgroundColor = item.color return div }else{ throw new Error('未知元素类型') } } // good cosnt createElement =(item)=>{ const validTypes = ['ball', 'block', 'image'] if(!validTypes.includes(item.type)){ throw new Error('未知元素类型') } cosnt div = document.createElement('div') div.className = item.type div.style.backgroundColor = item.color return div } // bad let commodity = { phone: '手机', computer: '电脑', television: '电视', gameBoy: '游戏机', } function price(name) { if (name === commodity.phone) { console.log(1999) } else if (name === commodity.computer) { console.log(9999) } else if (name === commodity.television) { console.log(2999) } else if (name === commodity.gameBoy) { console.log(3999) } } price('手机') // 1999 // good const commodity = new Map([ ['phone', 1999], ['computer', 9999], ['television', 2999], ['gameBoy', 3999], ]) const price = (name) => { return commodity.get(name) } price('phone') // 1999
-
-
可维护性类
-
// bad if (state === 1 || state === 2) { // ... } else if (state === 3) { // ... } // good const UNPUBLISHED = 1; const PUBLISHED = 2; const DELETED = 3; if (state === UNPUBLISHED || state === PUBLISHED) { // ... } else if (state === DELETED) { // ... } -
// bad class User { userName; userAge; userPwd; userLogin() { }; userRegister() { }; } // good class User { name; age; pwd; login() {}; register() {}; } - anyScript
- 重复代码 — 主要看有没有把公用组件,可复用的代码,函数抽取出来
- 代码注释 — 注释不明确或者缺少注释
-
-
边界问题
-
性能问题
-
安全问题
- xss攻击
React 中使用 `dangerouslySetInnerHTML` 或者 Vue 中使用 `v-html` 都会引入 XSS 攻击风险。 在 JSX 层面处理 HTML 拼接相关逻辑,避免 dangerouslySetInnerHTML 的使用。 在必需要 dangerouslySetInnerHTML 的地方,增加 excapeHTML() 方法过滤、净化来自用户侧的不可靠内容。