javascript
JS语言核心
? ? ? ?有些東西,對于初學者來說,可能看不懂,我在這里只是想說一下,JS里面有這么個情況,并不是說讓你掌握,你只需要大致瀏覽一下就可以了。
//?所有在雙斜杠之后的內(nèi)容都屬于注釋
//變量是表示值的一個符號名字
//變量通過var關(guān)鍵字來聲明,案例:
var?x;//聲明一個變量x
?
//值可以通過等號賦值給變量
x=0;??//現(xiàn)在變量x的值為0
x //=>0:通過變量獲取其值
?
//JS支持多種數(shù)據(jù)類型
x=1; //數(shù)字
x=0.01; //整數(shù)和實數(shù)公用一種數(shù)據(jù)類型
x=”hello?world”; //由雙引號內(nèi)的文本構(gòu)成的字符串
x=’JavaScript’; //單引號內(nèi)的文本同樣構(gòu)成字符串
x=true; //布爾值
x=false; //另一個布爾值
x=null; //null是一個特殊的值,意思是”空”
x=undefined; //undefined和null非常類似
?
JS中有兩個非常重要的數(shù)據(jù)類型分別是對象和數(shù)組.
?
?
//JS中最重要的類型就是對象
//對象是名/值對的集合,或字符串到值映射的集合,案例:
var?book={ //對象是由花括號括起來的
topic:”JS”, //屬性topic的值是JS
fat:true //屬性fat的值是true
}; 右花括號標記了對象的結(jié)束,記得分號
?
//通過”.”或者”[]”來訪問對象屬性
book.topic ? ? ? ? ? // ? ? =>”JS”
book[“fat”] ? ? ? ? ? ?// ? ?=>true:另外一種獲取屬性的方式
book.author=”syx”;//通過賦值創(chuàng)建一個新屬性
book.contents={}; //{}是一個空對象,特沒有屬性
?
?
//JS同樣支持數(shù)組(以數(shù)字為索引的列表)
var?primes=[2,3,4,5]; //擁有四個值的數(shù)組,有”[”和”]”劃定邊界
primes[0] //=>2:數(shù)組中的第一個元素(索引為0)
primes.Length //=>4:數(shù)組中的元素個數(shù)
primes[primes.Length-1]??//=>5:數(shù)組中隊后一個元素
primes[100]=99? //通過賦值來添加新元素
primes[100]=-99 //或通過賦值來改變已有的元素
var?expty=[]; //[]是空數(shù)組,它具有0個元素
empty.Length //=>0
?
//數(shù)組和對象中都可以包含另一個數(shù)組或?qū)ο?案例:
var?points=[ //具有兩個元素的數(shù)組
{x:0,y:0}, //每個元素都是一個對象
{x:1,y:1}
];
?
var?data={ //一個包含兩個屬性的對象
trial1:?[[1,2],[3,4]],//每個屬性都輸數(shù)組
trial2:?[[2,3],[4,5]]//數(shù)組的元素也是數(shù)組
};
?
上述代碼通過方括號定義數(shù)組元素和通過花括號定義對象屬性名和屬性值之間的映射關(guān)系的語法稱為初始化表達式.所謂的表達式是JS中的一個短語,這個短語可以通過運算得出一個值.通過點號(.)和方括號([])來引用對象屬性或數(shù)組元素的值就構(gòu)成了一個表達式.另外注釋中的箭頭(=>)表示表達式的運算結(jié)果.
?
JS中最常見的表達式寫法是像如下案例一樣使用運算符:
//運算符作用域操作數(shù),生成一個新的值
//最常見的是算術(shù)運算符
?
3+2? //=>5:加法
3-2 //=>1:減法
3*2 //=>6:乘法
3/2 //=>1.5”除法
points[1].x-points[0].x??//=>1:更復雜的操作數(shù)也能照常工作
“3”+”2” //=>”32”:+可以完成加法運算符也可以作字符串連接
?
//JS還定義了一些算術(shù)運算符的簡寫形式
var?count=0; //定義一個變量
count++; //自加1,和++count的效果一樣,同理還有自減
count*=2; //自乘2,相當于count=count*2
?
?
//相等關(guān)系運算符用來判斷是否相等
//不等,大于,小于運算符的運算結(jié)果是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中的”短語”是表達式的話,那么整個句子就叫做語句,以分號結(jié)束的行均是一條語句.實際上,語句和表達式之間有很多共同之處,粗略的講,表達式僅僅計算出一個值但并不做任何操作,他并不是改變程序的運行狀態(tài).而語句并不包含一個值(或者說它包含的值我們不關(guān)心),但語句能改變程序的運行狀態(tài).比如有一類語句叫做”控制語句”.
?
函數(shù)是帶有名稱和參數(shù)的JS代碼段,可以一次定義多次使用.案例:
function?plus1(x){ //定義了名為plus1的一個函數(shù),帶有參數(shù)x
return?x+1; //返回一個比傳入的參數(shù)大1的值
} //函數(shù)的代碼塊是由花括號包裹起來的部分
?
var?y=3;
plus1(y) //=>4:y為3,調(diào)用函數(shù)的結(jié)果為3+1
?
var?square=function(x){ //函數(shù)是一種值,可以賦值給變量
return?x*x; //計算函數(shù)的值
} //分號表示了賦值語句的結(jié)束
square(plus1(y)) //=>16:在一個表達式調(diào)用兩個函數(shù)
注釋:這里的”名稱”是指函數(shù)具有固定標識,并不是指函數(shù)變量的名稱.
?
?
//當函數(shù)賦值給對象的屬性,我們稱為”方法”,所有的JS對象都含有方法
?
var?a=[]; //創(chuàng)建一個空數(shù)組
a.push(1,2,3); //push()方法像數(shù)組中添加元素
a.reverse(); //另一個方法:將數(shù)組元素的次序反轉(zhuǎn)
//我們也可以定義自己的方法,”this”關(guān)鍵字是對定義方法的
//對象的引用:這里的例子是上面提到的包含兩個點位置信息的數(shù)組
?
points.dist=function(){ //定義一個方法來計算兩點之間的舉例
var?p1=this[0]; //通過this獲得對當前數(shù)組的引用
var?p2=this[1]; //并取得調(diào)用的數(shù)組前兩個元素
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:求得兩個點之間的距離
?
?
?
現(xiàn)在給出一些控制語句的而例子,這里的實例函數(shù)體內(nèi)包含了最常見的JS控制語句:
//這些JS語句使用該語法包含條件判斷和循環(huán)
//使用了類似C,C++,JAVA和其他語言的語法
?
function?abs(x){ //求絕對值的函數(shù)
if(x>=0) //if語句
{
return?x; //如果比較結(jié)果為true則執(zhí)行這里的代碼
} //子句的結(jié)束
else{ //當if條件不滿足時執(zhí)行else子句
return?-x; //如果分支中只有一條語句,花括號是可以省略的
} //注意if/else中嵌套的return語句
}
?
?
?
function?factorial(n){ //計算階乘的函數(shù)
var?product?=1; //給product賦值為1
while(n>1){ //當()內(nèi)的表達式為true時循環(huán)執(zhí)行{}內(nèi)的代碼
product*=n; //"product=product*n;"的簡寫形式
n--; //"n=n-1;"的簡寫形式
} //循環(huán)結(jié)束
return?product; //返回product
}
?
factorial(4) //=>24:1*4*3*2
?
?
function?factorial2(n){ //實現(xiàn)循環(huán)的另一種方式
var?i,product=1; //給rpoduct賦值為1
for(i=2;i<=n;++i) //將i從2自增至n
product*=i; //循環(huán)體,當循環(huán)體中只有一句代碼時,可以省略{}
?
return?product;//返回計算好的階乘
}
factorial2(5) //=>120:1*2*3*4*5
?
?
JS是一種面向?qū)ο蟮木幊陶Z言,但和傳統(tǒng)的面向?qū)ο笥钟泻艽髤^(qū)別.
?
//定義一個構(gòu)造函數(shù)以初始化一個新的Point對象
function?Point(x,y){ //按照慣例,構(gòu)造函數(shù)均以大寫字母開始
this.x=x; //關(guān)鍵字this指代此函數(shù)的實例
this.y=y; //將函數(shù)參數(shù)存儲為對象的屬性
} //不需要return
?
?
//使用new關(guān)鍵字和構(gòu)造函數(shù)來創(chuàng)建一個實例
var?p=new?Point(1,1); //平面集合中的點(1,1)
?
//通過給構(gòu)造函數(shù)的prototype對象賦值來給Point對象定義方法
Point.prototype.r=function(){
return Math.sqrt(this.x*this.x+this.y*this.y)? //返回x*x+y*y的平方根,this指代調(diào)用這個方法的對象
}
?
?
//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>元素可以用來輸入數(shù)組
程序?qū)⒃?lt;span>元素中顯示計算結(jié)果,這些元素都具有類似"interset"和"years"的id
這些id將在表格下面的JS代碼中用到.我們注意到,有一些input元素定義了"onchange"或
"onclick"的事件處理程序,以便用戶在輸入數(shù)據(jù)或者點擊inputs時執(zhí)行指定的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"?οnchange="calculate();"/></td>
<td?rowspan="8"><canvas?id="graph"?width="400px"?height="250px"></canvas></td>
</tr>
?
<tr>
<td>Annual?interest(%):</td>
<td><input?id="apr"?οnchange="calculate();"/></td>
</tr>
?
<tr>
<td>Repayment?period?(years):?</td>
<td><input?id="years"?οnchange="calculate();"/></td>
</tr>
?
<tr>
<td>Zipcode?(to?find?lender)?:?</td>
<td><input?id="zipcode"?οnchange="calculate();"/></td>
</tr>
?
<tr>
<td>Approximate?Patments:?</td>
<td><button?οnclick="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代碼,這些代碼內(nèi)嵌在了一個<script>標簽里
通常情況下,這些腳本代碼應放在<head>標簽中
將JS代碼放在HTML代碼之后僅僅是為了便于理解
-->
?
?
<script>
"use?strict"; //如果瀏覽器支持的話,則凱奇ECMAScript?5的嚴格模式
/*這里的腳本定義了calculate()函數(shù),在HTML代碼中綁定事件處理程序時會調(diào)用它
這個函數(shù)從<input>元素中讀取數(shù)據(jù),計算貸款賠付信息,并將結(jié)果顯示在<span>元素中
同樣,這里還保存了用戶數(shù)據(jù),戰(zhàn)術(shù)了房貸人連接并繪制除了圖表
*/
?
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元素中獲取輸入數(shù)據(jù)
//將百分比格式轉(zhuǎn)換為小數(shù)個事,并從年利率轉(zhuǎn)換為月利率
//將年度賠付轉(zhuǎn)換為月度賠付
?
var?principal=parseFloat(amount.value);
var?interest=parseFloat(apr.value)/100/12;
var?payments=parseFloat(years.value)*12;
?
?
//現(xiàn)在計算月度賠付的數(shù)據(jù)
var?x=Math.pow(1+interest,payments);//Math.pow()進行冪次運算
var?monthly=(principal*x*interest)/(x-1);
?
//如果結(jié)果沒有超過JS能表示的書子范圍,且用戶的輸入也正確
//這里所展示的結(jié)果就是合法的
?
if(isFinite(monthly))
{
//將數(shù)據(jù)填充至輸出字段的位置,四舍五入到小數(shù)點后兩位數(shù)字
?
payment.innerHTML=monthly.toFixed(2);
total.innerHTML=(monthly*payments).toFixed(2);
totalinterest.innerHTML=((monthly*payments)-principal).toFixed(2);
?
//將用戶的輸入數(shù)據(jù)保存下來,這樣在下次訪問時也能渠道數(shù)據(jù)
?
save(amount.value,apr.value,years.value,zipcode.value);
?
//找到并展示本地放貸人,但忽略網(wǎng)絡錯誤
?
try{//捕獲這段代碼拋出的所有異常
getLenders(amount.value,apr.value,years.value,zipcode.value)
}
catch(e){//忽略這些異常
}
//最后,用圖表展示貸款余額,利息和資產(chǎn)收益
chart(principal,interest,monthly,payments);
}
else{
//計算結(jié)果不是數(shù)字或者無窮大,意味著輸入數(shù)據(jù)是非法或不完整的
//清空之前的輸出數(shù)據(jù)
payment.innerHTML="";//清空元素的文本內(nèi)容
total.innerHTML="";
totalinterest.innerHTML="";?
chart(); //不傳參數(shù)的話就是清除圖表
}
}
?
?
/*
將用戶的輸入保存至localStorage對象的屬性中
這些屬性在再次訪問時還會繼續(xù)保存在原位置
如果你在瀏覽器中按照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.οnlοad=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;
?
}
};
?
?
/*
將用戶的輸入發(fā)送至服務器端腳本(理論上)將
返回一個本地放貸人的鏈接列表,在這里例子中并沒有實現(xiàn)這種查找放貸人的服務
但如果該服務存在,該函數(shù)會使用它
?
*/
?
function?getLenders(amount,apr,years,zipcode){
//如果瀏覽器不支持XMLHttpRequest對象,則退出
if(!window.XMLHttpRequest)
return?;
?
//找到要顯示放貸人列表的元素
?
var?ad=document.getElementById("lenders");
?
if(!ad)
return?;//如果返回為空,則退出
?
//將用戶的輸入數(shù)據(jù)進行URL編碼,并作為查詢參數(shù)負載URL里
?
var?url="getLenders.php"+//處理數(shù)據(jù)的URL地址
"?amt="+encodeURIComponent(amount)+//使用查詢串中的數(shù)據(jù)
"&apr="+encodeURIComponent(apr)+
"&yrs="+encodeURIComponent(years)+
"&zip="+encodeURIComponent(zipcode);
?
?
//通過XMLHttpRequest();
var?req=new?XMLHttpRequest(); //發(fā)起一個新的請求
req.open("GET",url); //通過URL搭起一個HTTP?GET請求
req.send(null); //不帶任何正文發(fā)送這個請求,這句話有錯誤,但是不耽誤程序的運行,不知道為啥有錯誤,大神求解
?
?
/*
在返回數(shù)據(jù)之前,注冊了一個數(shù)件處理函數(shù),這個函數(shù)
將會在服務器的響應返回至客戶端的時候調(diào)用
這種異步編程模型在客戶端JS中是很常見的
*/
?
req.onreadystatechange=function(){
if(req.readyState==4&&req.status==200){
//如果代碼運行到這里,說明我們得到了一個合法且完整的HTTP響應
var?response=req.responseText;//HTTP響應是以字符串的形式呈現(xiàn)的
var?lenders=JSON.parse(response);?//將其解析為JS數(shù)組
?
//講述組中的放貸人對象轉(zhuǎn)換為HTML字符串形式
var?list="";
for(var?i=0;i<lenders.length;++i){
list+="<li><a?href='"+lenders[i].url+"'>"+lenders[i].name+"</a>";
}
//將數(shù)據(jù)在HTML元素中呈現(xiàn)出來
ad.innerHTML="<ul>"+list+"</ul>";
}
}
}
?
?
?
/*
在HTML<canvas>元素中用途變展示月度貸款余額,利息和資產(chǎn)收益
如果不傳入?yún)?shù)的話,則清空之前的圖表數(shù)據(jù)
?
*/
function?chart(principal,interest,monthly,payments){
var?graph=document.getElementById("graph");//得到<canvas>標簽
graph.width=graph.width;//用一種巧妙手法清除并重置畫布
?
//如果不傳入?yún)?shù),或者瀏覽器不支持畫布,則直接返回
if(arguments.length==0||!graph.getContext)return?;
?
//獲得畫布元素的"context"對象,這個對象定義了一組繪畫API
?
var?g=graph.getContext("2d");//所有的繪畫操作都將基于這個對象
?
var?width=graph.width;
?
var?height=graph.height;//獲得畫布大小
?
//這里的函數(shù)作用是將付款數(shù)字和美元數(shù)據(jù)轉(zhuǎn)換為像素
function?paymentToX(n){
return?n*width/payments;
}
function?amountToY(a){
return?height-(a*height/(monthly*payments*1.05));
}
?
//付款數(shù)據(jù)是一條從(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(); //將結(jié)尾連接至開頭
?
g.fillStyle="#f88"; //亮紅色
g.fill(); //填充矩形
?
g.font="bold?12px?sans-serif"; //定義一種字體
?
g.fillText("Total?Interset?Payments?",20,20); //將文字繪制到圖例中
//很多資產(chǎn)數(shù)據(jù)并不是線性的,很難將其反映至圖表中
?
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);//得到資產(chǎn)額
g.lineTo(paymentToX(p),amountToY(equity));//將數(shù)據(jù)繪制到畫布上
}
?
g.lineTo(paymentToX(payments),amountToY(0));//將數(shù)據(jù)線繪制至x軸
g.closePath(); //將線條結(jié)尾連接至線條開頭
g.fillStyle="green"; //使用綠色繪制圖形
g.fill(); //曲線之下的部分均填充
?
g.fillText("Total?Equity",20,35); //文本顏色設置為綠色
?
//再次循環(huán),余額數(shù)據(jù)顯示為黑色粗線條
?
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);//得到凈資產(chǎn)
g.lineTo(paymentToX(p),amountToY(bal));//將直線連接至某點
}
g.lineWidth=3; //將直線寬度加粗
g.stroke(); //繪制余額的曲線
g.fillStyle="black"; //使用黑色字體
g.fillText("Loan?Balance",20,50);//圖例文字
?
?
//將年度數(shù)據(jù)在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)//每五年的數(shù)據(jù)
g.fillText(String(year),x,y-5);
}
?
//將賠付數(shù)額標記在右邊界
g.textAlign="right"; //文本右對齊
g.textBaseline="middle";//文字垂直居中
var?ticks=[monthly*payments,principal];//我們將要用到的兩個點
var?rightEdge=paymentToX(payments);//設置X坐標
for(var?i=0;i<ticks.length;++i){//對每兩個點做循環(huán)
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); //不帶任何正文發(fā)送這個請求,這句話有錯誤,但是不耽誤程序的運行,不知道為啥有錯誤,大神求解
為什么上來就來這么一個案例呢,我想告訴你,別小看任何一門語言,JS能實現(xiàn)其他語言實現(xiàn)不了的東西,JS有它獨特的魅力,在生活中也是一樣,永遠不要輕易的看不起別人,蔑視別人.
總結(jié)
- 上一篇: MySQL 打开federated存储引
- 下一篇: Object C为UILabel添加点击