基本重構:不要重複自己
重構是編輯代碼以提高效率和可讀性而不改變輸出的過程。我做了一個小例子來演示初學者如何開始重構他們的代碼。這個迷你教程涵蓋了 DRY(不要重複自己)的概念,將來可能會派上用場。
假設我有一些 JavaScript/JSON 對像或數組形式的數據。數據及其格式化方式在這裡並不重要,它可能要復雜得多,但為了舉例,我將把它簡單化。 (它可能來自 API,但我將省略此示例中獲取數據的步驟,因為它無關緊要。)這是我們的數據:
數據var sessions = {
mobile: [1, 2, 3],
tablet: [3, 4, 5],
desktop: [6, 7, 8],
}
現在假設我有一個函數需要多次運行該數據。也許我正在通過 API 發送它以繪製圖表。在這種情況下,我將數據打印到網站(DOM)。
功能function printData(id, name, sessions) {
var div = document.createElement('div')
div.id = id
div.textContent = name + ' : ' + sessions
document.querySelector('body').appendChild(div)
}
於是就有了我的通用代碼:數據和函數。
var sessions = {
mobile: [1, 2, 3],
tablet: [3, 4, 5],
desktop: [6, 7, 8],
}
function printData(id, sessions) {
var div = document.createElement('div')
div.id = id
div.textContent = name + ' : ' + sessions
document.querySelector('body').appendChild(div)
}
原碼
因此,對於我的第一次嘗試,我將手動通過代碼運行數據。我在一個變量中為需要傳遞給函數的數據創建了一個對象。
// collapsing for brevity
var sessions = { ... }
function printData(id, name, sessions) { ... }
// Manually create objects and assign each one to a variable
var mobileData = {
id: 'mobile-container',
name: 'mobile',
sessions: sessions['mobile']
};
var tabletData = {
id: 'tablet-container',
name: 'tablet',
sessions: sessions['tablet']
};
var desktopData = {
id: 'desktop-container',
name: 'desktop',
sessions: sessions['desktop']
};
我使用每個對象的屬性調用該函數。
// Manually invoke function
printData(mobileData.id, mobileData.name, mobileData.sessions)
printData(tabletData.id, tabletData.name, tabletData.sessions)
printData(desktopData.id, desktopData.name, desktopData.sessions)
顯然,這段代碼效率很低。我看到很多重複。我知道冗餘很糟糕,但我不一定知道如何解決它。所以這就是我們要做的事情。
重構
首先,我將使用 Object.keys
創建一個包含所有鍵值的數組 .
var sessions = { ... }
function printData(id, name, sessions) { ... }
var devices = Object.keys(sessions); // returns [ "mobile", "tablet" ... ]
然後我將創建一個對像數組,其中包含我需要的所有屬性。我將使用 map()
來執行此操作 .
var sessions = { ... }
function printData(id, name, sessions) { ... }
var devices = Object.keys(sessions);
var data = devices.map(function(device) {
// returns [{ ... }, { ... }, { ... }], an array of objects
return {
id: device + '-container',
name: device,
sessions: sessions[device],
}
});
最後,我會做一個 forEach()
循環為每個對象運行一次函數。
data.forEach(function (device) {
printData(device.id, device.sessions)
})
就是這樣!就在下面。
fullCode.jsvar sessions = {
mobile: [1, 2, 3],
tablet: [3, 4, 5],
desktop: [6, 7, 8],
}
var printData = function (id, name, sessions) {
var div = document.createElement('div')
div.id = id
div.textContent = name + ' : ' + sessions
document.querySelector('body').appendChild(div)
}
var devices = Object.keys(sessions)
var data = devices.map(function (device) {
return {
id: device + '-container',
name: device,
sessions: sessions[device],
}
})
data.forEach(function (device) {
printData(device.id, device.name, device.sessions)
})
在這裡它用一些 ES6 語法進行了更新。
fullCodeES6.jsconst sessions = {
mobile: [1, 2, 3],
tablet: [3, 4, 5],
desktop: [6, 7, 8],
}
const printData = (id, name, sessions) => {
var div = document.createElement('div')
div.id = id
div.textContent = `${name} : ${sessions}`
document.querySelector('body').appendChild(div)
}
const devices = Object.keys(sessions)
const data = devices.map((device) => {
return {
id: `${device}-container`,
name: device,
sessions: sessions[device],
}
})
data.forEach((device) => {
printData(device.id, device.name, device.sessions)
})
現在,代碼可能不會那麼短,但想像一下如果我們的數據有 50 個條目而不是 3 個條目。然後你就真的開始看到好處了。
請注意,更少的代碼或更短的代碼不一定是更好的代碼。您不應該為了簡潔而犧牲可讀性和清晰性。
- 這是上面代碼示例的演示。