第二章 JS語法

第二章 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 注釋###

  1. //注釋一行
  2. /* abc */注釋一段
  3. ``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中是可以的。
  1. 字符串喉誊,字符串由零個或多個字符構成邀摆。

    var mood ="don't ask";
    
  2. 數(shù)值,可以用整數(shù)伍茄,也可以是浮點數(shù)

    var age=33.25;
    
  3. 布爾值(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)建的對象务热,本書不討論。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末己儒,一起剝皮案震驚了整個濱河市崎岂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闪湾,老刑警劉巖冲甘,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異途样,居然都是意外死亡江醇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門何暇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來陶夜,“玉大人,你說我怎么就攤上這事裆站√醣伲” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵宏胯,是天一觀的道長羽嫡。 經常有香客問我,道長肩袍,這世上最難降的妖魔是什么杭棵? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮了牛,結果婚禮上颜屠,老公的妹妹穿的比我還像新娘辰妙。我一直安慰自己,他們只是感情好甫窟,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布密浑。 她就那樣靜靜地躺著,像睡著了一般粗井。 火紅的嫁衣襯著肌膚如雪尔破。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天浇衬,我揣著相機與錄音懒构,去河邊找鬼。 笑死耘擂,一個胖子當著我的面吹牛胆剧,可吹牛的內容都是我干的。 我是一名探鬼主播醉冤,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼秩霍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蚁阳?” 一聲冷哼從身側響起铃绒,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎螺捐,沒想到半個月后颠悬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡定血,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年赔癌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片糠悼。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡届榄,死狀恐怖,靈堂內的尸體忽然破棺而出倔喂,到底是詐尸還是另有隱情铝条,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布席噩,位于F島的核電站班缰,受9級特大地震影響,放射性物質發(fā)生泄漏悼枢。R本人自食惡果不足惜埠忘,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧莹妒,春花似錦名船、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鉴腻,卻和暖如春迷扇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爽哎。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工蜓席, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人课锌。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓厨内,卻偏偏與公主長得像,于是被迫代替她去往敵國和親渺贤。 傳聞我的和親對象是個殘疾皇子隘庄,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內容

  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點點福利:阿里云產品券癣亚,享受所有官網(wǎng)優(yōu)惠,并抽取幸運大...
    HetfieldJoe閱讀 3,037評論 3 37
  • 特別說明获印,為便于查閱述雾,文章轉自https://github.com/getify/You-Dont-Know-JS...
    殺破狼real閱讀 568評論 0 0
  • 一直以來,我都有一個幻象兼丰,我總覺得有個人在我身邊看著我玻孟,也保護著我。 曾經我把TA對號入座為我外婆鳍征,哪怕她已經早早...
    微光之冕閱讀 125評論 0 0
  • 今天由于缺少實際的目標黍翎,也沒干成什么事,不管是代碼還是看文檔都興趣缺缺……總之就是繼續(xù)鼓搗drools引擎艳丛。 晚上...
    真晝之月閱讀 193評論 0 0
  • 特想和大家分享寒假里看的兩部劇匣掸,美劇《this is us》 and 韓劇《我親愛的朋友們》 輯一【《this i...
    沙小樹閱讀 238評論 0 0