第二章 JS語法
- 語句
- 變量和數(shù)組
- 操作符
- 條件語句和循環(huán)語句
- 函數(shù)與對象
2.1 準備工作
用JS寫的代碼必須通過HTML/XHTML文檔才能執(zhí)行其监。兩個方法:
- 將JS代碼放到文檔
<head>
標簽中的<script>
標簽之間
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Example</title>
<script>
JavaScript goes here...
</script>
</head>
<body>
mark-up goes here...
</body>
</html>
- 把JS代碼存為一個擴展名為.js的獨立文件励翼。典型的做法是在文檔的
<head>
部分放一個<script>
標簽蛋勺,并把它的src屬性指向該文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Example</title>
<script src="file.js"></script>
</head>
<body>
mark-up goes here...
</body>
</html>
- 但最好的做法是把
<script>
標簽放到HTML文檔的最后,</body>
標簽之前。這樣能使瀏覽器更快的加載頁面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Example</title>
</head>
<body>
mark-up goes here...
<script src="file.js"></script>
</body>
</html>
程序語言分為解釋型和編譯型兩大類较幌。JAVA/C++等需要一個編譯器(complier)。編譯器是一種程序白翻,能夠把用JAVA等高級語言寫出來的源代碼翻譯為直接在計算機上執(zhí)行的文件乍炉。
解釋型語言不需要編譯器,他們僅需要解釋器滤馍。在互聯(lián)網(wǎng)環(huán)境下岛琼,web瀏覽器負責完成有關的解釋和執(zhí)行工作。解釋型的語言代碼中的錯誤只能等到解釋器執(zhí)行到有關代碼才能發(fā)現(xiàn)巢株。
2.2 語法##
與其他腳本語言一樣槐瑞,都由一系列指令構成。這些指令叫做語句(statement)阁苞。
2.2.2 注釋###
- //注釋一行
-
/* abc */
注釋一段 - ``HTML風格困檩,如果使用,JS要求每行開頭都由`
2.2.3 變量###
賦值(assignment)
mood="happy";
age=33;
一個變量被賦值以后那槽,就說該變量包含這個值悼沿。
alert(mood);
alert(age);
JS中沒要求必須提前聲明變量,但這是一個好習慣骚灸。下面語句對變量做出了聲明:
var mood;
var age;
或者:var mood, age;
甚至可以把聲明和賦值一起完成:
var mood="happy";
var age=33;
甚至還可以這樣:var mood="happy", age=33;
JS變量名區(qū)分大小寫糟趾。
為了讓比較長的變量易讀,可在變量名中加下劃線甚牲。(第一個字符不允許是數(shù)字)义郑。
另一種是用駝峰格式(camel case),刪除中間的空白(下劃線)丈钙,后面的每個新單詞改用大寫字母開頭:
var myMood="happy";
通常駝峰格式是函數(shù)名魔慷,方法名和對象屬性名命名的首選格式。
2.2.4 數(shù)據(jù)類型###
有些語言要求在聲明變量的同時還必須聲明變量的數(shù)據(jù)類型著恩,此做法叫類型聲明(typing)
JS是弱類型(weakly typed)語言,意味著可以再任何階段改變變量的數(shù)據(jù)類型
var age= "thirty three";
age=33;
這在JS中是可以的。
-
字符串喉誊,字符串由零個或多個字符構成邀摆。
var mood ="don't ask";
-
數(shù)值,可以用整數(shù)伍茄,也可以是浮點數(shù)
var age=33.25;
-
布爾值(boolean)
var sleeping=true;
但是var married="true";
就是設成了字符串
2.2.5 數(shù)組###
用一個變量來存儲一組值栋盹,就需要使用數(shù)組(array)
數(shù)組是指用一個變量表示一個值的集合,集合中的每個值都是這個數(shù)組的一個元素(element)敷矫。在JS中例获,數(shù)組可以用關鍵字Array聲明。聲明的同時還可以指定數(shù)組初始元素的個數(shù)曹仗、長度榨汤。
var beatles=Array(4);
如果無法預知數(shù)組長度,可以不聲明怎茫。
var beatles=Array();
向數(shù)組中添加元素稱為填充 (populating)
array[index]=element;
例如:
var beatles=Array(4);
beatles[0]="John";
beatles[1]="Paul";
beatles[2]="George";
beatles[3]="Ringo";
然后就可以通過標值來獲取元素收壕,例如用beatles[2]
來獲取"George"。
注意數(shù)組下標是從0開始計數(shù)的
或者還有一種簡單的方式:聲明數(shù)組的同時進行填充
var beatles=Array("John","Paul"轨蛤,"George","Ringo");
數(shù)組元素也可以是混合的數(shù)據(jù)類型:
var lennon=["John",1900,false];
數(shù)組元素還可以是變量:
var name="John";
beatles[0]=name;
或者可以指定變量賦值給數(shù)組:
var names=["Ringo","John","Geogre","Paul"];
beatles[1]=names[3];
數(shù)組還可以包含別的數(shù)組:
var lennon=["John",1900,false];
var beatles=[];
beatles[0]=lennon;
如此蜜宪,beatles數(shù)組的第一個元素就是另外一個數(shù)組,要想獲得二級數(shù)組的值要用更多的括號祥山,beatles[0][0]就是"John",beatles[0][1]就是1900,beatles[0][2]就是false圃验。
這種方法的缺點在于不得不記住每個下標的數(shù)字。首先看一種更可讀的填充數(shù)組的方式缝呕,然后介紹存放數(shù)據(jù)的首選方式:將數(shù)據(jù)保存為對象
2.2.5.1 關聯(lián)數(shù)組####
如果在填充數(shù)組的時候只給出了元素的值澳窑,這個數(shù)組就是一個傳統(tǒng)數(shù)組,他的各個元素的下標將被自動創(chuàng)建和刷新岳颇。
可以通過在填充數(shù)組時為每個新元素明確的給出下標來改變這種默認的行為照捡。在為新元素給出下標時,不必局限于整數(shù)數(shù)字话侧,還可使用字符串栗精。
var lennon=Array();
lennon["name"]="John";
lennon["year"]=1900;
lennon["living"]=false;
這樣的數(shù)組就是關聯(lián)數(shù)組
關聯(lián)數(shù)組的理解:
由于使用了字符串來替代數(shù)字值,因而代碼更具有可讀性瞻鹏。但這不是一種好習慣悲立,不推薦使用。本質上新博,在創(chuàng)建關聯(lián)數(shù)組時薪夕,創(chuàng)建的都是Array對象的屬性。在JS中所有的變量都是某種類型的對象赫悄。比如一個布爾值就是一個Boolean類型的對象原献。本例子中實際上是給lennon數(shù)組添加了name,year,living三個屬性馏慨。理想情況下,不該修改Array對象的屬性姑隅,二應該使用通用的對象(Object)写隶。
2.2.6 對象###
上一節(jié)的lennon數(shù)組可以變成下面的對象:
var lennon=Object();
lennon.name="John";
lennon.year=1900;
lennon.living=false;
創(chuàng)建對象使用Object關鍵字,不使用方括號和下標來獲取元素讲仰,而是點號來獲取屬性慕趴。
創(chuàng)建對象還有一種更簡潔的語法,花括號語法:
{propertyName:value, propertyName:value}
比如Lennon對象可以寫成這樣:
var lennon={name:"John", year:1940, living:false};
如果現(xiàn)在還用lennon來填充beatles數(shù)組鄙陡,就簡單多了:
var beatles=Array();
beatles[0]=lennon;
此時只需beatles[0].name
就能得到"John"
再舉個例子:
var beatles={};
beatles.vocalist=lennon;
現(xiàn)在beatles.vocalist.name
的值就是"John"
2.3 操作##
JS也要做一些計算和處理數(shù)據(jù)冕房,也就需要完成一些操作(operation).
算術操作符###
+,-趁矾,=耙册,/,*愈魏,+=
給一個數(shù)值變量加1觅玻,year++
給一個數(shù)值變量減1,year--
加號還可用于字符串培漏,把兩個字符串合二為一溪厘。這種操作叫拼接(concatenation)
var message="I am feeling "+"happy";
或者
var mood="happy";
var message="I am feeling "+mood;
注意,如果將字符串和數(shù)值拼接在一起牌柄,結果是更長的字符串
alert("10"+20);
alert(10+20);
第一條返回“1020”,第二條返回30
2.4 條件語句##
if 語句:
if(condition){
statements;
}
if語句的花括號并不是必不可少的畸悬。如果只有一條語句的話,就可以不用花括號珊佣。
if(1〉2) alert("the world has gone mad!");
if還可以有一個else子句蹋宦,包含在else子句中的語句會在給定條件為假時執(zhí)行。
if (1>2){
alert("1");
}else{
alert("2");
}
注意單個等號是賦值咒锻,雙等號才是判定是否一致
var my_mood="happy";
if(my_mood=="happy")
全等===
相等操作符==并不表示嚴格相等冷冗,例如false與一個空字符比較:
var a=false;
var b="";
if(a==b){
alert("a equals b");
}
這條語句的求值結果為true,因為相等操作符==認為空字符串與false的含義相同惑艇。要進行嚴格比較就要用全等===蒿辙。這個操作符會執(zhí)行嚴格的比較,不僅比較值滨巴,而且會比較變量的類型思灌。
對于不等操作符!=也是一樣的恭取,如果想比較嚴格的不相等泰偿,就要使用!==蜈垮。
邏輯操作符
與: &&
或:||
非:耗跛!
2.5 循環(huán)語句##
工作原理:只要給定條件仍能得到滿足裕照,包含在循環(huán)語句里的代碼就將重復的執(zhí)行下去;一旦給定條件的求值結果不再是true课兄,循環(huán)也就到此為止牍氛。
while循環(huán)
while(condtion){
statements;
}
do...while循環(huán)###
在某些場合,我們希望循環(huán)語句內部的代碼至少執(zhí)行一次烟阐,就要用到do...while循環(huán):
do{
statements;
}while(condition);
即使循環(huán)控制條件的首次求值結果是false,包含在花括號里的語句也至少會被執(zhí)行一次。
var count=1;
do{
alert(count);
count++;
}while(count<11);
for循環(huán)###
for循環(huán)只是while循環(huán)的一種遍體紊扬。
initialize;
while(condition){
statements;
increment;
}
而for循環(huán)不過是進一步改寫為更緊湊的形式:
for(initial condition; test condition; alter condition){
}
用for循環(huán)的好處是循環(huán)控制結構更清晰蜒茄,與循環(huán)有關的所有內容都包含在圓括號里。這樣我們可以知道那些代碼將被執(zhí)行多少次餐屎。
注意:
for循環(huán)最常見的用途是對某個數(shù)組里的全體元素進行遍歷檀葛。這往往要用到數(shù)組的array.length屬性。一定要記住腹缩,數(shù)組的下標是從0開始而不是1開始屿聋。
2.6 函數(shù)##
如果需要多次使用同一段代碼,可以把他們封裝成一個函數(shù)藏鹊。事實上润讥,每個函數(shù)都是一個短小的腳本。
作為一種良好的習慣盘寡,應該先對函數(shù)作出定義再調用他們楚殿。
function shout(){
var beatles=Array("John","Paul","George","Ringo");
for(var count=0;count<beatles.length;count++){
alert(beatles[count]);
}
}
可以隨時使用如下的語句來調用這個函數(shù):
shout();
昧旦需要反復做一件事時,都可以利用函數(shù)來避免重復鍵入大量相同內容竿痰。不過函數(shù)的真正威力體現(xiàn)在脆粥,你可以把不同的數(shù)據(jù)傳遞給他們,而他們將使用這些數(shù)據(jù)去完成預訂的操作
我們把傳遞給函數(shù)的數(shù)據(jù)稱為參數(shù)(argument)影涉。
定義一個函數(shù)的語法:
function name(arguments){
statements;
}
JS提供里許多內建函數(shù)变隔,如alert()。在定義函數(shù)時蟹倾,可以為聲明任意多個參數(shù)匣缘,只要用逗號把他們分割開來就行,在函數(shù)內部喊式,可以像使用普通變量那樣使用他的任何一個參數(shù)孵户。
函數(shù)的返回數(shù)據(jù)
return語句:
function multiply(num1, num2){
var total=num1 *num2;
return total;
}
函數(shù)的真正價值體現(xiàn)在,我們還可以把他們當作一種數(shù)據(jù)類型來使用岔留,這以為著可以把一個函數(shù)的調用結果賦給一個變量
var temp_fahrenheit=95;
var temp_celsius=convertToCelsius(temp_fahrenheit);
alert(temp_celsius);
駝峰命名法
在命名變量時夏哭,用下劃線來分隔各個單詞。
在命名函數(shù)時献联,從第二個單詞開始把每個單詞的第一個字母寫成大寫形式竖配。
與變量的情況一樣何址,JS不允許函數(shù)的名字里包含空格。
變量的作用域###
變量既可以是全局的进胯,也可以是局部的用爪。他們之間的區(qū)別,其實是變量的作用域(scope)胁镐。
全局變量(global variable)
可以在腳本中的任何位置被引用偎血。一旦在某個腳本里聲明了全局變量,就可以從這個腳本的任何位置包括函數(shù)內部引用它盯漂。全局變量的作用域時整個腳本颇玷。
局部變量(local variable)
只存在于聲明它的那個函數(shù)內部,在那個函數(shù)的外部是無法引用它的就缆。作用域僅限于某個特定的函數(shù)帖渠。
如果在函數(shù)中使用來var
,那個變量就是一個局部變量
如果沒有使用var
竭宰,那就是一個全局變量空郊,如果腳本里已經存在一個與之同名的全局變量,這個函數(shù)就會改變那個全局變量的值
舉個例子:
function square(num){
total = num * num;
return total;
}
var total = 50;
var number = square (20);
alert (total);
這些代碼會導致全局變量total的值變?yōu)?00切揭;我的本意時讓square()函數(shù)只把它計算出來的平方值返回給變量number狞甚,但因為未把這個函數(shù)內部的total變量明確的聲明為局部變量,這個函數(shù)把名字同樣時total的那個局部變量的值也改變了伴箩。
例子應這么寫:
function square(num){
var total = num*num;
return total;
}
記住入愧,函數(shù)在行為方面應該像一個自給自足的腳本。在定義一個函數(shù)時嗤谚,我們一定要把它內部的變量全都明確的聲明為局部變量棺蛛。如果你總是在函數(shù)里使用var
關鍵字來定義變量,就能避免任何形式的二義性隱患巩步。
2.7 對象##
對象時自包含的數(shù)據(jù)集合旁赊,包含在對象里的數(shù)據(jù)可以通過兩種形式訪問,屬性(property)和方法(method):
屬性是隸屬于某個特定對象的變量
方法是只有某個特定對象才能調用的函數(shù)
對象就是由一些屬性和方法組合在一起而構成的一個數(shù)據(jù)尸體實體
在JS中椅野,屬性和方法都是使用“點”來訪問:
Object.property();
Object.method();
例如:
Person.mood;
Person.age;
Person.walk();
Person.sleep();
這些屬性和方法全部集合在一起终畅,就得到來一個Person對象。
為了使用Person對象來描述一個特定的人,需要創(chuàng)建一個Person對象的實例(instance)
為給定對象創(chuàng)建一個實例,需要使用new
關鍵字
var jeremy = new Person;
上面這條語句創(chuàng)建一個Person對象的新實例jeremy,我們就可以使用Person的屬性來檢索關于jeremy的信息:
jeremy.age;
jeremy.mood;
2.7.1 內建對象###
預先定義好的對象垦藏,就是內建對象(native object)。數(shù)組就是其中一種妖爷,當我們用new
去初始化一個數(shù)組時,其實就是在創(chuàng)建一個Array對象的新實例理朋。
var beatles = new Array();
beatles.length();
其他的內建對象絮识,比如 Math對象和 Date對象绿聘。
Math對象的round方法可以把十進制的數(shù)值舍入一個與之最接近的整數(shù):
var num=7.561;
var num=Math.round(num);
alert(num);
Date對象可以用來存儲和檢索與特定日期和事件有關的信息。在創(chuàng)建Date對象 的新實例時次舌,JS解釋器會使用當前日期和時間對它進行初始化熄攘。
var current_date = new Date();
還有getDay(),getHours(),getMonth()等一系列方法:
var today = current_date.getDay();
2.7.2 宿主對象###
還有些預先定義好的其他對象,他們不是由JS而是由運行環(huán)境本身提供彼念。具體到web應用挪圾,就是瀏覽器。由瀏覽器提供的與定義對象被稱為宿主對象(host object)国拇。
宿主對象包括Form,Image和Element等洛史。我們可以通過他們獲得關于網(wǎng)頁上的表單、圖像和各種表單元素等信息酱吝。
另一種宿主對象也能獲得網(wǎng)頁上的任何一個元素信息,它就是document對象土思。
2.7.3 用戶定義對象###
user-defined object, 由程序員自行創(chuàng)建的對象务热,本書不討論。