今天趁空闲时间,让同事优化一段之前匆忙写的代码(主要优化写法问题)。在优化过程中暴露出了一些很小,但很严重的问题。在此记下,以作警示。
下面一段是本次需要优化的代码
function initSubmitData() {
for (let i = 0 i < this.exam.length i++) {
this.submitData[i] = []
for (let j = 0 j < this.exam[i].topicList.length j++) {
if (this.exam[i].topicList[j].topicAttachment && typeof this.exam[i].topicList[j].topicAttachment === 'string') {
this.exam[i].topicList[j].topicAttachment = JSON.parse(this.exam[i].topicList[j].topicAttachment)
}
if (this.exam[i].topicList[j].topicOption && typeof this.exam[i].topicList[j].topicOption === 'string') {
this.exam[i].topicList[j].topicOption = JSON.parse(this.exam[i].topicList[j].topicOption)
}
let content = this.exam[i].topicList[j]
this.submitData[i][j] = {
topicId: content.topicID,
topicTypeId: content.topicType,
paperTopicScore: content.topicScore,
standardAudio: content.topicAttachment.length > 0 ? Config.res + content.topicAttachment[0].attachmentUrl : '',
standardAnswer: '',
myAnswer: '',
isAudio: false,
audioAnswerList: []
}
if (Object.prototype.toString.call(content.topicOption) === '[object Array]') {
for (let k = 0 k < content.topicOption.length k++) {
this.submitData[i][j].audioAnswerList[k] = {
coreType: '',
score: '',
audioUrl: '',
standardAudio: '',
recordId: '',
attributes: ''
}
}
} else {
this.submitData[i][j].audioAnswerList[0] = {
coreType: '',
score: '',
audioUrl: '',
standardAudio: '',
recordId: '',
attributes: ''
}
}
}
}
}
下面是改写中的重灾区:
/*
* 这是每个人都会提取出来的变量
*/
let _def = {
coreType: '',
score: '',
audioUrl: '',
standardAudio: '',
recordId: '',
attributes: ''
}
/*
* 下面就是重灾区了
*/
for ( ... ) {
someObj.array.push(_def)
}
这样单独列出来之后,问题在哪,想必各位一目了然了。但事实上,在整个代码里面,一旦不留意,就很容易发生这种 传值 和 传址 的问题,当发生bug,调试的时候还不容易发现。
下面还有个错误写法
// 接上面一段代码
// ...
someObj.array = someObj.array.concat([])
这个错误的是对 concat
方法的理解不全面,concat
方法是 浅拷贝(shallow copy),虽然会生成一个新的数组,但数组里面的 值 该是 地址 的还是 地址 ,就好比狼已经入室了,这时候再关门,为时已晚。
最后放出一段优化过的代码(也许还能优化,欢迎提出)
function initSubmitData() {
const _default = {
coreType: '',
score: '',
audioUrl: '',
standardAudio: '',
recordId: '',
attributes: ''
}
for (let i = 0; i < this.exam.length; i++) {
this.submitData[i] = []
for (let j = 0; j < this.exam[i].topicList.length; j++) {
let content = this.exam[i].topicList[j]
let topicAttachment = content.topicAttachment
let topicOption = content.topicOption
typeof topicAttachment === 'string' && (content.topicAttachment = JSON.parse(topicAttachment))
typeof topicOption === 'string' && (content.topicOption = JSON.parse(topicOption))
let oData = this.submitData[i][j] = {
topicId: content.topicID,
topicTypeId: content.topicType,
paperTopicScore: content.topicScore,
standardAudio: topicAttachment.length ? Config.res + topicAttachment[0].attachmentUrl : '',
standardAnswer: '',
myAnswer: '',
isAudio: false,
audioAnswerList: []
}
const array = topicOption instanceof Array ? topicOption : [1]
for (let k = 0; k < array.length; k++) {
oData.audioAnswerList[k] = Object.assign({}, _default)
}
}
}
}
最后,我同事问我,这种优化代码有意思吗?我觉得,这是培养一种码代码的习惯,好的编码习惯益处多多,在此就不累述了。