今天趁空閑時間,讓同事優(yōu)化一段之前匆忙寫的代碼(主要優(yōu)化寫法問題)。在優(yōu)化過程中暴露出了一些很小,但很嚴重的問題。在此記下,以作警示。
下面一段是本次需要優(yōu)化的代碼
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: ''
}
}
}
}
}
下面是改寫中的重災(zāi)區(qū):
/*
* 這是每個人都會提取出來的變量
*/
let _def = {
coreType: '',
score: '',
audioUrl: '',
standardAudio: '',
recordId: '',
attributes: ''
}
/*
* 下面就是重災(zāi)區(qū)了
*/
for ( ... ) {
someObj.array.push(_def)
}
這樣單獨列出來之后,問題在哪,想必各位一目了然了。但事實上,在整個代碼里面,一旦不留意,就很容易發(fā)生這種 傳值 和 傳址 的問題,當(dāng)發(fā)生bug,調(diào)試的時候還不容易發(fā)現(xiàn)。
下面還有個錯誤寫法
// 接上面一段代碼
// ...
someObj.array = someObj.array.concat([])
這個錯誤的是對 concat
方法的理解不全面,concat
方法是 淺拷貝(shallow copy),雖然會生成一個新的數(shù)組,但數(shù)組里面的 值 該是 地址 的還是 地址 ,就好比狼已經(jīng)入室了,這時候再關(guān)門,為時已晚。
最后放出一段優(yōu)化過的代碼(也許還能優(yōu)化,歡迎提出)
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)
}
}
}
}
最后,我同事問我,這種優(yōu)化代碼有意思嗎?我覺得,這是培養(yǎng)一種碼代碼的習(xí)慣,好的編碼習(xí)慣益處多多,在此就不累述了。