JS语言核心
有些东西,对于初学者来说,可能看不懂,我在这里只是想说一下,JS里面有这么个情况,并不是说让你掌握,你只需要大致浏览一下就可以了.
// 所有在双斜杠之后的内容都属于注释
//变量是表示值的一个符号名字
//变量通过var关键字来声明,案例:
var x;//声明一个变量x
//值可以通过等号赋值给变量
x=0; //现在变量x的值为0
x //=>0:通过变量获取其值
//JS支持多种数据类型
x=1; //数字
x=0.01; //整数和实数公用一种数据类型
x=”hello world”; //由双引号内的文本构成的字符串
x=’JavaScript’; //单引号内的文本同样构成字符串
x=true; //布尔值
x=false; //另一个布尔值
x=null; //null是一个特殊的值,意思是”空”
x=undefined; //undefined和null非常类似
JS中有两个非常重要的数据类型分别是对象和数组.
//JS中最重要的类型就是对象
//对象是名/值对的集合,或字符串到值映射的集合,案例:
var book={ //对象是由花括号括起来的
topic:”JS”, //属性topic的值是JS
fat:true //属性fat的值是true
}; 右花括号标记了对象的结束,记得分号
//通过”.”或者”[]”来访问对象属性
book.topic //=>”JS”
book[“fat”] //=>true:另外一种获取属性的方式
book.author=”syx”;//通过赋值创建一个新属性
book.contents={}; //{}是一个空对象,特没有属性
//JS同样支持数组(以数字为索引的列表)
var primes=[2,3,4,5]; //拥有四个值的数组,有”[”和”]”划定边界
primes[0] //=>2:数组中的第一个元素(索引为0)
primes.Length //=>4:数组中的元素个数
primes[primes.Length-1] //=>5:数组中队后一个元素
primes[100]=99 //通过赋值来添加新元素
primes[100]=-99 //或通过赋值来改变已有的元素
var expty=[]; //[]是空数组,它具有0个元素
empty.Length //=>0
//数组和对象中都可以包含另一个数组或对象,案例:
var points=[ //具有两个元素的数组
{x:0,y:0}, //每个元素都是一个对象
{x:1,y:1}
];
var data={ //一个包含两个属性的对象
trial1: [[1,2],[3,4]],//每个属性都输数组
trial2: [[2,3],[4,5]]//数组的元素也是数组
};
上述代码通过方括号定义数组元素和通过花括号定义对象属性名和属性值之间的映射关系的语法称为初始化表达式.所谓的表达式是JS中的一个短语,这个短语可以通过运算得出一个值.通过点号(.)和方括号([])来引用对象属性或数组元素的值就构成了一个表达式.另外注释中的箭头(=>)表示表达式的运算结果.
JS中最常见的表达式写法是像如下案例一样使用运算符:
//运算符作用域操作数,生成一个新的值
//最常见的是算术运算符
3+2 //=>5:加法
3-2 //=>1:减法
3*2 //=>6:乘法
3/2 //=>1.5”除法
points[1].x-points[0].x //=>1:更复杂的操作数也能照常工作
“3”+”2” //=>”32”:+可以完成加法运算符也可以作字符串连接
//JS还定义了一些算术运算符的简写形式
var count=0; //定义一个变量
count++; //自加1,和++count的效果一样,同理还有自减
count*=2; //自乘2,相当于count=count*2
//相等关系运算符用来判断是否相等
//不等,大于,小于运算符的运算结果是true或false
var x=2,y=3; //这里的等号(=)是赋值的意思,不是比较的意思
x==y //=>false:相等操作符
x!=y //=>true:不等运算符
//同理还有<,>,<=,>=
“one”==”two” //=false:两个字符串不行等
“two”>”one” //=>true:”t”在字母表中的索引大于”o”
false==(x>y) //=>true:false和false相等
//逻辑运算符是对布尔值的合并或求反
(x==2)&&(y==3) //=>true:两个比较都是true,&&表示”与”
(x>3)||(y<3) //=>false:两个比较都不是true,||表示”或”
!(x==y) //=>true:!求反
如果JS中的”短语”是表达式的话,那么整个句子就叫做语句,以分号结束的行均是一条语句.实际上,语句和表达式之间有很多共同之处,粗略的讲,表达式仅仅计算出一个值但并不做任何操作,他并不是改编程序的运行状态.而语句并不包含一个值(或者说它包含的值我们不关心),但语句能改变程序的运行状态.比如有一类语句叫做”控制语句”.
函数是带有名称和参数的JS代码段,可以一定定义多次使用.案例:
function plus1(x){ //定义了名为plus1的一个函数,带有参数x
return x+1; //返回一个比传入的参数大的值
} //函数的代码块是由花括号包裹起来的部分
var y=3;
plus1(y) //=>4:y为3,调用函数的结果为3+1
var square=function(x){ //函数是一种值,可以赋值给变量
return x*x; //计算函数的值
} //分号标示了赋值语句的结束
square(plus1(y)) //=>16:在一个表达实例调用两个函数
注释:这里的”名称”是指函数具有固定标识,并不是指函数变量的名称.
//当函数赋值给对象的属性,我们称为”方法”,所有的JS对象都含有方法
var a=[]; //创建一个空数组
a.push(1,2,3); //push()方法像数组中添加元素
a.reverse(); //另一个方法:讲述组元素的次序反转
//我们也可以定义自己的方法,”this”关键字是对定义方法的
//对象的引用:这里的例子是上面提到的包含两个点位置信息的数组
points.dist=function(){ //定义一个方法来计算两点之间的举例
var p1=this[0]; //通过this获得对当前数组的引用
var p2=this[1]; //并取得调用的数组前两个元素
var a=p2.x-p1.xl; //x坐标轴上的距离
var b=p2.y-p1.y; //y坐标轴上的距离
return Math.sqrt(a*a+b*b); //勾股定理,使用Math.sqrt()来计算两点之间的距离
}
points.dist() //=>1.414:求得两个点之间的距离
现在给出一些控制语句的而梨子,这里的实例函数体内包含了最常见的JS控制语句:
//这些JS语句使用该语法包含条件判断和循环
//使用了类似C,C++,JAVA和其他语言的语法
function abs(x){ //求绝对值的函数
if(x>=0) //if语句
{
return x; //如果比较结果为true则执行这里的代码
} //子句的结束
else{ //当if条件不满足时执行else子句
return -x //如果分支中只有一条语句,花括号是可以省略的
} //注意if/else中嵌套的return语句
}
function factorial(n){ //计算阶乘的函数
var product =1; //给product赋值为1
while(n>1){ //当()内的表达式为true时循环执行{}内的代码
product*=n; //"product=product*n;"的简写形式
n--; //"n=n-1;"的简写形式
} //循环结束
return product; //返回product
}
factorial(4) //=>24:1*4*3*2
function factorial2(n){ //实现循环的另一种方式
var i,product=1; //给rpoduct赋值为1
for(i=2;i<=n;++i) //将i从2自增至n
product*=i; //循环体,当循环体重只有一句代码时,可以省略{}
return product;//返回计算好的阶乘
}
factorial2(5) //=>120:1*2*3*4*5
JS是一种面向对象的编程语言,但和传统的面向对象又有很大区别.
//定义一个构造函数以初始化一个新的Point对象
function Point(x,y){ //按照惯例,构造函数均以大写字母开始
this.x=x; //关键字this指代吃书画的实例
this.y=y; //将函数参数存储为对象的属性
} //不需要return
//使用new关键字和构造函数来创建一个实例
var p=new Point(1,1); //平面集合中的点(1,1)
//通过给构造函数的prototye对象赋值来给Point对象定义方法
Point.prototye.r=function(){
return Math.sqrt(this.x*this.x+this.y*this.y) //返回x*x+y*y的平方根,this指代调用这个方法的对象
}
//Point的实例对象p(以及所有的Point实力对象)继承了r()
p.r() //=>1.414...
JS案例:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>JS Loan Calculator</title>
<style>/*这是一个CSS样式表:定义了程序输出的样式*/
.output
{
font-weight:bold;
}
#payment
{
text-decoration:underline;
}
#graph
{
border:solid black 1px;
}
</style>
</head>
<body>
<!--
这是一个HTML表格,其中包含<input>元素可以用来输入数组
程序将在<span>元素中显示计算结果,这些元素都具有类似"interset"和"years"的id
这些id将在表格下面的JS代码中用到.我们注意到,有一些input元素定义了"onchange"或
"onclick"的事件处理程序,以便用户在输入数据或者点击inputs时执行指定的JS代码
-->
<table>
<tr>
<th>Enter Loan Data:</th>
<th>Loan Balance,Cumulative Equity,and Interset Payments</th>
</tr>
<tr>
<td>Amount of the loan($):</td>
<td><input id="amount" onchange="calculate();"/></td>
<td rowspan="8"><canvas id="graph" width="400px" height="250px"></canvas></td>
</tr>
<tr>
<td>Annual interest(%):</td>
<td><input id="apr" onchange="calculate();"/></td>
</tr>
<tr>
<td>Repayment period (years): </td>
<td><input id="years" onchange="calculate();"/></td>
</tr>
<tr>
<td>Zipcode (to find lender) : </td>
<td><input id="zipcode" onchange="calculate();"/></td>
</tr>
<tr>
<td>Approximate Patments: </td>
<td><button onclick="calculate();">Calculate</button></td>
</tr>
<tr>
<td>Monthly payments: </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="totalinterset"></span></td>
</tr>
<tr>
<th>Sponsors :</th>
<td colspan="2">Apply for your loan with one if there fine lenders:
<div id="lenders"></div>
</td>
</tr>
</table>
<!--
随后是JS代码,这些代码内嵌在了一个<script>标签里
通常情况下,这些脚本代码应放在<head>标签中
将JS代码放在HTML代码之后仅仅是为了便于理解
-->
<script>
"use strict"; //如果浏览器支持的话,则凯奇ECMAScript 5的严格模式
/*这里的脚本定义了calculate()函数,在HTML代码中绑定事件处理程序时会调用它
这个函数从<input>元素中读取数据,计算贷款赔付信息,并将结果显示在<span>元素中
同样,这里还保存了用户数据,战术了房贷人连接并绘制除了图表
*/
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("totalinterset");
//假设所有的输入都是合法的,将从input元素中获取输入数据
//将百分比格式转换为小数个事,并从年利率转换为月利率
//将年度赔付转换为月度赔付
var principal=parseFloat(amount.value);
var interest=parseFloat(apr.value)/100/12;
var payments=parseFloat(years.value)*12;
//现在计算月度赔付的数据
var x=Math.pow(1+interest,payments);//Math.pow()进行幂次运算
var monthly=(principal*x*interest)/(x-1);
//如果结果没有超过JS能表示的书子范围,且用户的输入也正确
//这里所展示的结果就是合法的
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(); //不传参数的话就是清除图表
}
}
/*
将用户的输入保存至localStorage对象的属性中
这些属性在再次访问时还会继续保存在原位置
如果你在浏览器中按照file://URL的方式直接打开本地文件
则无法在某些浏览器中使用存储功能(如火狐)
而通过HTTP打开文件是可行的
*/
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 ;//如果返回为空,则退出
//将用户的输入数据进行URL编码,并作为查询参数负载URL里
var url="getLenders.php"+//处理数据的URL地址
"?amt="+encodeURIComponent(amount)+//使用查询串中的数据
"&apr="+encodeURIComponent(apr)+
"&yrs="+encodeURIComponent(years)+
"&zip="+encodeURIComponent(zipcode);
//通过XMLHttpRequest();
var req=new XMLHttpRequest(); //发起一个新的请求
req.open("GET",url); //通过URL搭起一个HTTP GET请求
req.send(null); //不带任何正文发送这个请求,这句话有错误,但是不耽误程序的运行,不知道为啥有错误,大神求解
/*
在返回数据之前,注册了一个数件处理函数,这个函数
将会在服务器的响应返回至客户端的时候调用
这种异步编程模型在客户端JS中是很常见的
*/
req.onreadystatechange=function(){
if(req.readyState==4&&req.status==200){
//如果代码运行到这里,说明我们得到了一个合法且完整的HTTP响应
var response=req.responseText;//HTTP响应是以字符串的形式呈现的
var lenders=JSON.parse(response); //将其解析为JS数组
//讲述组中的放贷人对象转换为HTML字符串形式
var list="";
for(var i=0;i<lenders.length;++i){
list+="<li><a href=‘"+lenders[i].url+"‘>"+lenders[i].name+"</a>";
}
//将数据在HTML元素中呈现出来
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;
var 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"; //定义一种字体
g.fillText("Total Interset 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));//将数据线绘制至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);//在坐标轴做标记
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>
</body>
</html>
分析:
req.send(null); //不带任何正文发送这个请求,这句话有错误,但是不耽误程序的运行,不知道为啥有错误,大神求解
为什么上来就来这么一个案例呢,我想告诉你,别小看任何一门语言,JS能实现其他语言实现不了的东西,JS有它独特的魅力,在生活中也是一样,永远不要轻易的看不起别人,蔑视别人.
版权声明:本文为博主原创文章,未经博主允许不得转载。