練習用的 REPL。
抽取時,若沒有任何變數會跑出 Scope,可以直接處理。
// Owing 欠款
function printOwing(invoice) {
let outstanding = 0;
console.log("***********************");
console.log("**** Customer Owes ****");
console.log("***********************");
// calculate outstanding(未清帳款)
for (const o of invoice.orders) {
outstanding += o.amount;
}
// record due date
const today = Clock.today;
invoice.dueDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30); // 別這樣做
// print details
console.log(`name: ${invoice.customer}`);
console.log(`amount: ${outstanding}`);
console.log(`due: ${invoice.dueDate.toLocaleDateString()}`);
}
function printOwing(invoice) {
let outstanding = 0;
printBanner(); // 先把畫 banner 的任務抽出來
// calculate outstanding
for (const o of invoice.orders) {
outstanding += o.amount;
}
// record due date
const today = Clock.today;
invoice.dueDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30);
// print details
console.log(`name: ${invoice.customer}`);
console.log(`amount: ${outstanding}`);
console.log(`due: ${invoice.dueDate.toLocaleDateString()}`);
}
function printBanner() { // 這裡不是 nested function
console.log("***********************");
console.log("**** Customer Owes ****");
console.log("***********************");
}
試著把註解內 print details
的部分都取出來。
function printOwing(invoice) {
let outstanding = 0;
printBanner();
// calculate outstanding
for (const o of invoice.orders) {
outstanding += o.amount;
}
// record due date
const today = Clock.today;
invoice.dueDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30);
printDetails();
function printDetails() { // 把印出 details 的任務再抽出來,這邊是 nested function,可以直接取用所有變數
console.log(`name: ${invoice.customer}`);
console.log(`amount: ${outstanding}`);
console.log(`due: ${invoice.dueDate.toLocaleDateString()}`);
}
}
function printBanner() { // 這裡不是 nested function
console.log("***********************");
console.log("**** Customer Owes ****");
console.log("***********************");
}
也可以直接傳遞變數
function printOwing(invoice) {
let outstanding = 0;
printBanner();
// calculate outstanding
for (const o of invoice.orders) {
outstanding += o.amount;
}
// record due date
const today = Clock.today;
invoice.dueDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30);
printDetails(invoice, outstanding);
}
function printDetails(invoice, outstanding) { // 不是 nested-function,需要傳遞參數
console.log(`name: ${invoice.customer}`);
console.log(`amount: ${outstanding}`);
console.log(`due: ${invoice.dueDate.toLocaleDateString()}`);
}
有時候,需要處理一下變數才能抽取。
function printOwing(invoice) {
let outstanding = 0;
printBanner();
// calculate outstanding
for (const o of invoice.orders) {
outstanding += o.amount;
}
recordDueDate(invoice);
printDetails(invoice, outstanding);
}
function printOwing(invoice) {
printBanner();
// calculate outstanding
let outstanding = 0; // 換位子,方便抽取成 function
for (const o of invoice.orders) {
outstanding += o.amount;
}
recordDueDate(invoice);
printDetails(invoice, outstanding);
}
function printOwing(invoice) {
printBanner();
// calculate outstanding
let outstanding = 0;
for (const o of invoice.orders) {
outstanding += o.amount;
}
recordDueDate(invoice);
printDetails(invoice, outstanding);
}
function calculateOutstanding(invoice) { // 經過 slide statement 後,可以整塊複製貼上
let outstanding = 0;
for (const o of invoice.orders) {
outstanding += o.amount;
}
return outstanding;
}
function printOwing(invoice) {
printBanner();
let outstanding = calculateOutstanding(invoice); // 把程式碼換成 function
recordDueDate(invoice);
printDetails(invoice, outstanding);
}
function calculateOutstanding(invoice) {
let outstanding = 0;
for (const o of invoice.orders) {
outstanding += o.amount;
}
return outstanding;
}
function printOwing(invoice) {
printBanner();
const outstanding = calculateOutstanding(invoice); // 改成 const,避免被意外重新賦值
recordDueDate(invoice);
printDetails(invoice, outstanding);
}
function calculateOutstanding(invoice) {
let result = 0; // 命名成 result 是 Martin Fowler 的習慣
for (const o of invoice.orders) {
result += o.amount;
}
return result;
}