一、基本类型
数组,使用“[]”中括号;该数组由两个对象组成,结构需要一致。
var points=[
{x:0,y:0},
{x:1,y:1},
];
对象,使用“{}”花括号;改对象有两个属性,两个属性的值都是为二维数组。
var data={
trial1:[[1,2],[3,4]],
trial2:[[2,3],[4,5]]
};
二、方法
当函数赋值给对象的属性时,我们称之为方法。所有的JavaScript对象都有方法,下面是个简单的例子,计算两点之间的距离:
points.dist = function(){
var p1 = this[0];
var p2 = this[1];
var a = p2.x - p1.x;
var b = p2.y - p1.y;
return Math.sqrt(a*a+b*b);
};
//控制台输出
console.log(points.dist());
三、控制语句
1、语句示例:
分别为判断、while循环以及for循环。
points.abs = function(x){
if(x>=0){
return x;
}else{
return -x;
}
};
points.factorial = function(n){
var product =1;
while(n>1){
product *=n;
n--;
}
return product;
};
points.factoria2 = function(n){
var i,product =1;
for (i = 2; i <= n; i++) {
product*=i;
};
return product;
};
2、表达式语句
1、赋值语句:i*=1
2、函数调用:window.close();
3、复合语句和空语句
1、复合语句使用{},将几条语句组合成复合语句。
2、空语句示例:for ( i = 0 ; i < a.length ; a[i++] = 0 ) ;
JavaScript中没有块级作用域。
使用空语句最好在其上面添加注释。因为你不知道你什么时候会看漏这个小分号。
4、声明语句
var 声明变量;function 声明函数;
1、函数声明:函数被提前,所以其他地方可以直接使用。
function fn(str)
{
console.log(str);
};
2、函数表达式定义:只有var fnx被提前,要等到运行到这个位置才可以使用fnx。
var fnx=function(str)
{
console.log(str+ ' from fnx');
};
下面的例子网上看到的,可以比较清晰的看到两者的区别
console.log(typeof(fn)); // function
fn('abc'); // abc
console.log(typeof(fnx)); // undefined
if(fnx)
fnx('abc'); // 不会执行。undefined。
else
console.log('fnx is undefined'); // 输出该方法未定义。
// 函数语句
function fn(str)
{
console.log(str);
};
// 表达式定义
var fnx=function(str)
{
console.log(str+ ' from fnx');
};
5、循环语句
var person = {
name:"lion",
age:25,
addr:"cz"
}
for(var o in person){
console.log(person[o]);
}
var array = [1,2,3,4,5,6]
for(var o in array){
console.log(o);
}
如果是对象,输出内容为对象可枚举属性的值。
如果是数组,输出内容为数组的索引,如果用delete array[0],枚举的索引会少个0。
6、跳转
带标签
function getData(){
var array=[[1,,3],,[3,4,5],[4,5,6]];
return array;
}
var matrix = getData();
var sum = 0,success = false;
compute_sum: if(matrix){
for(var x=0;x<matrix.length;x++){
var row = matrix[x];
if(!row) break compute_sum;
for(var y=0;y<row.length;y++){
var cell = row[y];
if(isNaN(cell))break compute_sum;
sum+= cell;
}
}
success = true;
}
success=false,数组存在异常。
四、类,构造函数,对象
1、构造函数首字母都是大写,通过new和构造函数创建一个实例对象。
2、通过给构造函数的prototype对象赋值,来给构造函数(类)定义方法。
PS:想要给实例对象创建方法,是通过指定方法给实例对象的属性;而如果要给构造函数(类)的所有实例对象都指定一个方法,就要用到构造函数的prototype对象了。
function Point(x,y){
this.x = x;
this.y = y;
}
var p = new Point(1,1);
var q = new Point(2,2);
p.r=function(){//此时只给实例对象p定义方法r();
return Math.sqrt(this.x*this.x+this.y*this.y);
}
console.log(p.r()); //1.4142135623730951
console.log(q.r()); //输出时会报错。TypeError: q.r is not a function
function Point(x,y){
this.x = x;
this.y = y;
}
var p = new Point(1,1);
var q = new Point(2,2);
Point.prototype.r=function(){//此时是给构造函数定义方法,需给prototype对象赋值。
return Math.sqrt(this.x*this.x+this.y*this.y);
}
console.log(p.r()); //1.4142135623730951
console.log(q.r()); //2.8284271247461903
1、对象
相关定义
1、对象是一种复合值
2、对象可以看做是属性的无序集合;
3、对象可以看成是从字符串到值的映射;
4、可以从一个称为原型的对象继承属性;
5、对象的方法通常是继承的属性;
6、对象是动态的,可以新增苏醒也可以删除属性;
7、对象最常见的用法是创建、设置、查找、删除、检测、枚举它的属性。
8、值可以是任意js值,也可以是一个getter或setter函数。
9、属性有一些与之相关的值,称为属性特性:可写、可枚举、可配置。
10、对象包含三个对象特性:对象的原型、对象的类、对象的扩展标记。
11、三类对象、两类属性
内置对象、宿主对象、自定义对象;
自由属性、继承属性。
创建对象:
通过对象直接量、关键字new、Object.create()函数 三种。
原型:
每一个JavaScript对象都和原型相关联,每个对象都从原型继承属性。
所有通过对象直接量创建的对象都具有同一个原型对象,
可以通过Object.prototype获得对原型对象的引用。
通过 new Object()创建的对象继承自Object.prototype;
通过 new Array()创建的对象原型是Array.prototype;
通过 new Date()创建的对象原型就是Date.prototype。
Object.create();
是一个静态函数,使用方法简单,只需要传入所需的原型对象即可。
var o1 = Object.create({x:1,y:2});
可以通过传入参数null创建一个没有原型的新对象
var o2 = Object.create(null);
如果想创建一个普通的空对象,需要传入Object.prototype;
var o3 = Object.create(Object.prototype);
五、创建DOM
下面示例,根据id获得div,如果没此div则生成一个,绑定参数到文本节点,输出到页面。
function debug(msg){
//通过查看HTML元素id来查找div
var log = document.getElementById('debuglog');
//如果元素不存在则创建一个
if(!log){
log = document.createElement('div');
log.id='debuglog';//给这个元素的id赋值
log.innerHTML = '<h1>Debug Log</h1>';//定义出事内容
document.body.appendChild(log);//添加到body的尾部
}
var pre = document.createElement('pre');
var text = document.createTextNode(msg);//将msg包装在一个文本节点中。
pre.appendChild(text);//文本添加到<pre>
log.appendChild(pre);//<pre>添加到log
}
debug('Test Debug');
六、客户端示例
使用canvas。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript Loan Calculator</title>
<style>
.output{
font-weight: bold; /* 计算结果为粗体*/
}
#payment{
text-decoration: underline;
}
#graph{
border: solid black 1px; /* 图表有1像素边框*/
}
th,td{
vertical-align: top; /* 表格顶端对齐*/
}
</style>
<script type="text/javascript">
function calculate(){
var amount = document.getElementById('amount');
var apr = document.getElementById('apr');
var years = document.getElementById('years');
var zipcode = document.getElementById('zipcode');
var payment = document.getElementById('payment');
var total = document.getElementById('total');
var totalinterest = document.getElementById('totalinterest');
//假设所有输入都是合法的,将从input元素中获取输入数据。
//将百分比格式转换为小数格式,并从年利率转换为月利率。
//将年度赔付转换为月度赔付。
var principal = parseFloat(amount.value);
var interest = parseFloat(apr.value);
var payments = parseFloat(years.value);
var x = Math.pow(1+interest, payments); //Math.pow()进行幂次运算
var monthly = (principal*x*interest)/(x-1);
//如果结果没有超过JavaScript能表示的数字范围,且用户输入也正确
//这里所展示的结果就是合法的。
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 ,apr.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){
document.getElementById('amount').value = localStorage.loan_amount;
document.getElementById('apr').value = localStorage.loan_apr;
document.getElementById('years').value = localStorage.loan_years;
document.getElementById('zipcode').value = localStorage.loan_zipcode;
}
};
function getLenders(amount,apr,years,zipcode){
//如果浏览器不支持XMLHttpRequest对象,则退出。
if(!window.XMLHttpRequest) return;
//找到要显示放贷人列表的元素
var ad = document.getElementById('lenders');
if(!ad)return; //如果返回为空,则退出
var url = "getLenders.php"+
"?amt=" + encodeURIComponent(amount)+
"&apr=" + encodeURIComponent(apr)+
"&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; i < lenders.length; i++) {
list+='<li><a href="'+lenders[i].url +'">'+lenders[i].name+'</a>';
}
ad.innerHTML = '<ul>' + list +'</ul>';
}
}
}
//HTML<canvas>元素中用图表展示月度贷款余额,利息,资产收益
//如果不传入参数,则清空之前的图表数据。
function chart(principal,interest,monthly,payments){
var graph = document.getElementById("graph");//得到<canvas>标签
graph.width = graph.width;//用一种巧妙的手法清除并重置画布
//如果不传入参数,或者浏览器不支持画布,则直接返回。
if(arguments.length == 0 || !graph.getContext)return;
//获取画布元素的“context”对象,这个对象定义了一组绘画API
var g =graph.getContext("2d"); //所有的绘画操作都将基于这个对象。
var width = graph.width,height = graph.height; //画布大小
function paymentToX(n){
return n*width/payments;
}
function amountToY(a){
return height - (a*height/(monthly*payments*1.05));
}
//付款数据是一条从(0,0)到(payments,monthly*payments)的直线。
g.moveTo(paymentToX(0),amountToY(0));//从左下方开始
g.lineTo(paymentToX(payments),amountToY(monthly*payments)); //绘至右上方。
g.lineTo(paymentToX(payments),amountToY(0)); //再至右下方。
g.closePath(); //将结尾连接至开头
g.fillStyle = "#f88";//亮红色
g.fill();//填充矩形
g.font = "bold 12px sans-serif";//将文字绘制到图中
//很多资产数据并不是线性的,很难将其反映至图表中
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));//将数据线绘制到x轴
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 Balance",20,50);
//将年度数据在x轴做标记
g.textAlign = "center"; //文字居中对齐
var y = amountToY(0); //Y坐标设为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); //每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); //设置x坐标
for(var i=0;i<ticks.length;i++){ //对每两个点做循环
var y = amountToY(ticks[i]); //计算每次标记的Y坐标
g.fillRect(rightEdge-3,y-0.5,3,1); //绘制标记
g.fillText(String(ticks[i].toFixed(0)),rightEdge-5,y); //绘制文本
}
}
</script>
</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 load ($):</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 period (years):</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>
<th>Aproximate Payments:</th>
<td><button onclick="calculate();">Calculate</button></td>
</tr>
<tr>
<td>Monthly payment:</td>
<td>$<span id="payment"></span></td>
</tr>
<tr>
<td>Total payment:</td>
<td>$<span id="total"></span></td>
</tr>
<tr>
<td>Total interest:</td>
<td>$<span 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>
</body>
</html>
效果图如下:(代码照抄还是写错了几个地方,不过用firebug,还是挺方便查出来问题的。)
不知道php文件的内容应该是获取某个url而已,对显示结果不影响。
看了上面的代码,发现一些有用的东西。
1、将一些数据放到浏览器,刷新后,数据也还在。
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){
document.getElementById('amount').value = localStorage.loan_amount;
document.getElementById('apr').value = localStorage.loan_apr;
document.getElementById('years').value = localStorage.loan_years;
document.getElementById('zipcode').value = localStorage.loan_zipcode;
}
};
2、
七、类型、值、变量
1、数据类型分两类:primitive type 原始类型和 object type 对象类型。
2、原始类型包括:number、string、boolean,两个特殊null 、undifined,除此之外都是对象。(但是对null使用 typeof,则显示的是object)
3、对象是 prototype 属性的集合,属性格式为(名:值)构成。
4、普通对象无序集合,特殊对象 array 数组表示带编号的有序集合。
5、第一种特殊对象 global object 全局对象。第二种特殊对象 函数,function 函数的定义为:函数是具有与其相关联的可执行代码的对象,通过调用函数来运行可执行代码,并返回运算结果。
6、如果函数用来初始化一个新建的对象,我们称之为构造函数,每个构造函数定义一 类对象,类可以看做是对象类型的子类型。
7、另外3种类:日期类Date、正则类RegExp、错误类Error。
8、面向对象语言。
9、js的变量是untype 无类型的,一个变量可以赋予不同类型的值。
八、数值
1、Date 日期类
var then = new Date(2011,0,1); //2011年1月1日
var later = new Date(2011,0,1,17,10,30); //2011年1月1日,5:10:30pm
var now = new Date(); //当前日期和时间。
var elapsed = new - then; //时间间隔的毫秒数
later.getFullYear();
later.getMonth();
later.getDate();
later.getDay(); //星期几,0为星期日,5为星期一
later.getHour(); //当地时间
later.getUTCHours() //使用UTC表示小时的时间