在 重构:改善既有代码的设计 (第2版) 中,js 嵌套函数的使用
1、在学习重构:改善既有代码的设计 (第2版)时,发现函数 statement 在末尾缺少1个 },进而导致代码格式显示上存在问题。如图1
function statement(invoice, plays) { let totalAmount = 0; let volumeCredits = 0; let result = `Statement for ${invoice.customer}\n`; const format = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", minimumFractionDigits: 2 }).format; for (let perf of invoice.performances) { let thisAmount = amountFor(perf , playFor(perf) ); // add volume credits volumeCredits += Math.max(perf.audience - 30, 0); // add extra credit for every ten comedy attendees if ("comedy" === playFor(perf).type) volumeCredits += Math.floor(perf.audience / 5); // print line for this order result += ` ${playFor(perf).name}: ${format(thisAmount / 100)} (${perf.audience} seats)\n`; totalAmount += thisAmount; } result += `Amount owed is ${format(totalAmount / 100)}\n`; result += `You earned ${volumeCredits} credits\n`; return result;
2、一直误以为是代码本身漏写了 },不得不自行补充上。最终的程序实现如下
<script> let invoice = { "customer": "BigCo", "performances": [ { "playID": "hamlet", "audience": 55 }, { "playID": "as-like", "audience": 35 }, { "playID": "othello", "audience": 40 } ] }; let plays = { "hamlet": { "name": "Hamlet", "type": "tragedy" }, "as-like": { "name": "As You Like It", "type": "comedy" }, "othello": { "name": "Othello", "type": "tragedy" } }; function playFor(aPerformance) { return plays[aPerformance.playID]; } function amountFor(aPerformance) { let result = 0; switch (playFor(aPerformance).type) { case "tragedy": result = 40000; if (aPerformance.audience > 30) { result += 1000 * (aPerformance.audience - 30); } break; case "comedy": result = 30000; if (aPerformance.audience > 20) { result += 10000 + 500 * (aPerformance.audience - 20); } result += 300 * aPerformance.audience; break; default: throw new Error(`unknown type: ${playFor(aPerformance).type}`); } return result; } function volumeCreditsFor(aPerformance) { let result = 0; result += Math.max(aPerformance.audience - 30, 0); if ("comedy" === playFor(aPerformance).type) result += Math.floor(aPerformance.audience / 5); return result; } function usd(aNumber) { return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", minimumFractionDigits: 2 }).format(aNumber / 100); } function totalVolumeCredits() { let result = 0; for (let perf of invoice.performances) { result += volumeCreditsFor(perf); } return result; } function totalAmount() { let result = 0; for (let perf of invoice.performances) { result += amountFor(perf); } return result; } function statement(invoice, plays) { let result = `Statement for ${invoice.customer}\n`; for (let perf of invoice.performances) { result += ` ${playFor(perf).name}: ${usd(amountFor(perf))} (${perf.audience} seats)\n`; } result += `Amount owed is ${usd(totalAmount())}\n`; result += `You earned ${totalVolumeCredits()} credits\n`; return result; } console.log(statement(invoice, plays)); </script>
3、在 1.5 进展:大量嵌套函数 重构至此,是时候停下来欣赏一下代码的全貌了。发现 函数 statement 的 } 竟然是存在的,只不过由于其中包含了一些嵌套函数,由于并非全貌,因此,并未显示出来。如图2
4、最终决定使用嵌套函数,仍然可以正常运行。如图3
<script> let invoice = { "customer": "BigCo", "performances": [ { "playID": "hamlet", "audience": 55 }, { "playID": "as-like", "audience": 35 }, { "playID": "othello", "audience": 40 } ] }; let plays = { "hamlet": { "name": "Hamlet", "type": "tragedy" }, "as-like": { "name": "As You Like It", "type": "comedy" }, "othello": { "name": "Othello", "type": "tragedy" } }; function statement(invoice, plays) { let result = `Statement for ${invoice.customer}\n`; for (let perf of invoice.performances) { result += ` ${playFor(perf).name}: ${usd(amountFor(perf))} (${perf.audience} seats)\n`; } result += `Amount owed is ${usd(totalAmount())}\n`; result += `You earned ${totalVolumeCredits()} credits\n`; return result; function totalAmount() { let result = 0; for (let perf of invoice.performances) { result += amountFor(perf); } return result; } function totalVolumeCredits() { let result = 0; for (let perf of invoice.performances) { result += volumeCreditsFor(perf); } return result; } function usd(aNumber) { return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", minimumFractionDigits: 2 }).format(aNumber / 100); } function volumeCreditsFor(aPerformance) { let result = 0; result += Math.max(aPerformance.audience - 30, 0); if ("comedy" === playFor(aPerformance).type) result += Math.floor(aPerformance.audience / 5); return result; } function playFor(aPerformance) { return plays[aPerformance.playID]; } function amountFor(aPerformance) { let result = 0; switch (playFor(aPerformance).type) { case "tragedy": result = 40000; if (aPerformance.audience > 30) { result += 1000 * (aPerformance.audience - 30); } break; case "comedy": result = 30000; if (aPerformance.audience > 20) { result += 10000 + 500 * (aPerformance.audience - 20); } result += 300 * aPerformance.audience; break; default: throw new Error(`unknown type: ${playFor(aPerformance).type}`); } return result; } } console.log(statement(invoice, plays)); </script>
近期评论