《JavaScript权威指南》第六版阅读笔记(一):JavaScript概述

时间:2022-08-27 08:14:07

  最近开始阅读《JavaScript权威指南》第六版,这次阅读的主要目地是进一步把基础打牢,对以前的学习复习和检查。

  第一章是JavaScript概述,没什么好说的,只把本章最后一个综合示例(贷款计算器)动手敲了一遍:

  代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Demo</title>
<style type="text/css">
.output
{
font-weight
:bold;
}
#payment
{
text-decoration
:underline;
}
#graph
{
border
:1px solid black;
}
th,td
{
vertical-align
:top;
}
</style>
</head>
<body>
<table>
<tr>
<th>Enter Loan Data:</th>
<td></td>
<th>Loan Balance,Cumulative Equity, and Interest Payments</th>
</tr>
<tr>
<td>Amount of the loan($):</td>
<td><input type="text" id="amount" onchange="calculate();"/></td>
<td rowspan=8>
<canvas id="graph" width="400" height="250"></canvas>
</td>
</tr>
<tr>
<td>Annual interest(%):</td>
<td><input type="text" id="apr" onchange="calculate();"/></td>
</tr>
<tr>
<td>Repayment penod(year):</td>
<td><input type="text" id="years" onchange="calculate();"/></td>
</tr>
<tr>
<td>Zipcode(to find lenders):</td>
<td><input type="text" id="zipcode" onchange="calculate();"/></td>
</tr>
<tr>
<td>Approximate Payments:</td>
<td><input type="button" value="Calculate" onclick="calculate();"/></td>
</tr>
<tr>
<td>Monthly payment:</td>
<td>$<span class="output" id="payment"></span></td>
</tr>
<tr>
<td>Total payment:</td>
<td>$<span class="output" id="total"></span></td>
</tr>
<tr>
<td>Total interest:</td>
<td>$<span class="output" id="totalinterest"></span></td>
</tr>
<tr>
<th>Sponsors:</th>
<td colspan="2">
Apply for your loan with one of these fine lenders:
<div id="lenders"></div></td>
</tr>
</table>
<script>
"use strict";

function $(id){
return document.getElementById(id);
}

function calculate(){
var amount=$("amount"),
apr
=$("apr"),
years
=$("years"),
zipcode
=$("zipcode"),
payment
=$("payment"),
total
=$("total"),
totalinterest
=$("totalinterest"),
principal
=parseFloat(amount.value),
interest
=parseFloat(apr.value)/100/12,
payments
=parseFloat(years.value)*12,
x
=Math.pow(1+interest,payments),
monthly
=(principal * x * interest)/(x-1);

if(isFinite(monthly)){
payment.innerHTML
= monthly.toFixed(2);
total.innerHTML
= (monthly * payments).toFixed(2);
totalinterest.innerHTML
= ((monthly * payments) - principal).toFixed(2);

save(amount.value,apr.value,years.value,zipcode.value);

try{
getLenders(amount.value,zpr.value,years.value,zipcode.value);
}
catch(e){

}

chart(principal,interest,monthly,payments);
}
else {
payment.innerHTML
="";
total.innerHTML
="";
totalinterest.innerHTML
="";
chart();
}
}

function save(amount,apr,years,zipcode){
if(window.localStorage){
localStorage.loan_amount
=amount;
localStorage.loan_apr
=apr;
localStorage.loan_years
=years;
localStorage.loan_zipcode
=zipcode;
}
}

window.onload
=function(){
if(window.localStorage && localStorage.loan_amount){
$(
"amount").value = localStorage.loan_amount;
$(
"apr").value = localStorage.loan_apr;
$(
"years").value = localStorage.loan_years;
$(
"zipcode").value = localStorage.loan_zipcode;
}
}

function getLenders(amount,zpr,years,zipcode){
if(window.XMLHttpRequest)
return;

var ad=$("lenders");
if(!ad)
return;

var url="genLenders.php"+
"?amt="+encodeURIComponent(amount)+
"&apr="+encodeURIComponent(zpr)+
"&yrs="+encodeURIComponent(years)+
"&zip="+encodeURIComponent(zipcode);

var req=new XMLHttpRequest();
req.open(
"GET",url);
req.send(
null);

req.onreadystatechange
=function(){
if(req.readyState == 4 && req.status == 200){
var response = req.responseText;
var lenders = JSON.parse(response);

var list="";
for(var i = 0, j = lenders.length; i<j; i++){
list
+="<li><a href='"+lenders[i].url+"'>" + lenders[i].name + "</a></li>";
}

ad.innerHTML
= "<ul>" + list + "</ul>";
}
}
}

function chart(principal, interest, monthly, payments){
var graph=$("graph");
//graph.width=graph.wdith;

if(arguments.length == 0 || !graph.getContext)
return;

var g=graph.getContext("2d"),
width
=graph.width,
height
=graph.height;

g.clearRect(
0, 0, width, height);

function paymentToX(n){
return n * width / payments;
}

function amountToY(a){
return height-(a * height / (monthly * payments * 1.05));
}

g.moveTo(paymentToX(
0),amountToY(0));
g.lineTo(paymentToX(payments),amountToY(monthly
* payments));
g.lineTo(paymentToX(payments),amountToY(
0));
g.closePath();
g.fillStyle
="#888";
g.fill();
g.fillText(
"Total Interest Payments",20,20);

var equity=0;
g.beginPath();
g.moveTo(paymentToX(
0),amountToY(0));
for(var p=1;p<= payments; p++){
var thisMonthsInterest = (principal - equity) * interest;
equity
+= (monthly - thisMonthsInterest);
g.lineTo(paymentToX(p),amountToY(equity));;
}
g.lineTo(paymentToX(payments),amountToY(
0));
g.closePath();
g.fillStyle
="green";
g.fill();
g.fillText(
"Total Equity",20,35);

var bal = principal;
g.beginPath();
g.moveTo(paymentToX(
0),amountToY(bal));
for(var p=1;p<=payments;p++){
var thisMonthsInterest=bal*interest;
bal
-=(monthly - thisMonthsInterest);
g.lineTo(paymentToX(p),amountToY(bal));
}
g.lineWidth
=3;
g.stroke();
g.fillStyle
="black";
g.fillText(
"Loan Black",20,50);
g.textAlign
="center";
var y=amountToY(0);
for(var year=1;year*12 <= payments; year++){
var x=paymentToX(year*12);
g.fillRect(x
-0.5,y-3,1,3);
if(year == 1){
g.fillText(
"year",x,y-5);
}
if(year % 5 == 0 && year * 12 !== payments){
g.fillText(String(year),x,y
-5);
}
}

g.textAlign
="right";
g.textBaseLine
="middle";
var ticks=[monthly * payments,principal];
var rightEdge = paymentToX(payments);
for(var i=0;i< ticks.length;i++){
var y=amountToY(ticks[i]);
g.fillRect(rightEdge
-3,y-0.5,3,1);
g.fillText(String(ticks[i].toFixed(
0)),rightEdge-5,y);
}
}
</script>
</body>
</html>

  运行效果:

  要注意的是书上的代码中有一行:

graph.width=graph.wdith;//用一种巧妙的手法清除并重置画布

  这一行代码经测试不能达到清除并重置画布的效果,反而使右达的图像只是一条垂直的黑线,所以我换成了:

g.clearRect(0, 0, width, height);

  也没找到勘误表,不在道这个地方是不是有印刷错误,如果有知道的朋烦请告知。:)