JavaScript簡介
區(qū)分大小寫
ECMAScript中的一切(變量膘盖、函數(shù)名和操作符)都區(qū)分大小寫鞋拟。
標(biāo)識符
指變量、函數(shù)蚌父、屬性的名字哮兰,或者函數(shù)的參數(shù)。標(biāo)識符可以是按照下列格式規(guī)則 組合起來的一或多個字符:
- 第一個字符必須是一個字母苟弛、下劃線(_)或一個美元符號($)喝滞;
- 其他字符可以是字母、下劃線膏秫、美元符號或數(shù)字右遭。
ECMAScript 標(biāo)識符采用駝峰大小寫格式,也就是第一個字母小寫缤削,剩下的每個單詞的 首字母大寫
不能把關(guān)鍵字窘哈、保留字、true亭敢、false 和null 用作標(biāo)識符宵距。
注釋
ECMAScript使用 C風(fēng)格的注釋,包括單行注釋和塊級注釋吨拗。單行注釋以兩個斜杠開頭满哪,如下所示:
// 單行注釋
塊級注釋以一個斜杠和一個星號(/)開頭,以一個星號和一個斜杠(/)結(jié)尾劝篷,如下所示:
/*
這是一個多行
(塊級)注釋
*/
嚴(yán)格模式
ECMAScript 5引入了嚴(yán)格模式(strict mode)的概念哨鸭。嚴(yán)格模式是為 JavaScript定義了一種不同的 解析與執(zhí)行模型。在嚴(yán)格模式下娇妓,ECMAScript 3中的一些不確定的行為將得到處理像鸡,而且對某些不安全 的操作也會拋出錯誤。要在整個腳本中啟用嚴(yán)格模式,可以在頂部添加如下代碼:
"use strict";
這行代碼看起來像是字符串只估,而且也沒有賦值給任何變量志群,但其實它是一個編譯指示(pragma), 用于告訴支持的 JavaScript引擎切換到嚴(yán)格模式蛔钙。這是為不破壞 ECMAScript 3語法而特意選定的語法锌云。
在函數(shù)內(nèi)部的上方包含這條編譯指示,也可以指定函數(shù)在嚴(yán)格模式下執(zhí)行:
function doSomething(){
"use strict";
//函數(shù)體
}
嚴(yán)格模式下吁脱,JavaScript 的執(zhí)行結(jié)果會有很大不同桑涎,因此本書將會隨時指出嚴(yán)格模式下的區(qū)別。
語句
ECMAScript中的語句以一個分號結(jié)尾兼贡;
關(guān)鍵字和保留字
ECMA-262描述了一組具有特定用途的關(guān)鍵字攻冷,這些關(guān)鍵字可用于表示控制語句的開始或結(jié)束,或 者用于執(zhí)行特定操作等遍希。按照規(guī)則等曼,關(guān)鍵字也是語言保留的,不能用作標(biāo)識符凿蒜。以下就是 ECMAScript 的全部關(guān)鍵字(帶*號上標(biāo)的是第 5版新增的關(guān)鍵字):
break do instanceof typeof case
else new var catch finally
return void continue for switch
while debugger* function this with default
if throw delete in try
ECMA-262還描述了另外一組不能用作標(biāo)識符的保留字涉兽。盡管保留字在這門語言中還沒有任何特定 的用途,但它們有可能在將來被用作關(guān)鍵字篙程。以下是 ECMA-262第 3版定義的全部保留字:
abstract enum int short boolean export interface static byte
extends long super char final native synchronized class float
package throws const goto private transient debugger implements protected
volatile double import public
第 5版把在非嚴(yán)格模式下運行時的保留字縮減為下列這些:
class enum extends super const export import
在嚴(yán)格模式下,第 5版還對以下保留字施加了限制:
implements package public interface private static let protected yield
變量
ECMAScript 的變量是松散類型的别厘,所謂松散類型就是可以用來保存任何類型的數(shù)據(jù)虱饿。定義變量時要使用 var 操作符,后跟變量名触趴,如下所示:
var message;
這行代碼定義了一個名為 message 的變量氮发,該變量可以用來保存任何值。ECMAScript也支持直接初始 化變量冗懦,因此在定義變量的同時就可以設(shè)置變量的值爽冕,如下所示:
var message = "hi";
像這樣初始化變量并不會把它標(biāo)記為字符串類型; 初始化的過程就是給變量賦一個值那么簡單披蕉。因此颈畸,可以在修改變量值的同時修改值的類型,如下所示:
var message = "hi"; message = 100; // 有效没讲,但不推薦
用 var 操作符定義的變量將成為定義該變量的作用域中的局部變量眯娱。也就是說, 如果在函數(shù)中使用 var 定義一個變量爬凑,那么這個變量在函數(shù)退出后就會被銷毀徙缴,例如:
function test(){
var message = "hi"; // 局部變量
}
test();
alert(message); // 錯誤!
這里嘁信,變量 message 是在函數(shù)中使用 var 定義的于样。當(dāng)函數(shù)被調(diào)用時疏叨,就會創(chuàng)建該變量并為其賦值。 而在此之后穿剖,這個變量又會立即被銷毀蚤蔓,因此例子中的下一行代碼就會導(dǎo)致錯誤。不過携御,可以像下面這 樣省略 var 操作符昌粤,從而創(chuàng)建一個全局變量:
function test(){
message = "hi"; // 全局變量
}
test();
alert(message); // "hi"
這個例子省略了 var 操作符,因而 message 就成了全局變量啄刹。這樣涮坐,只要調(diào)用過一次 test()函 數(shù),這個變量就有了定義誓军,就可以在函數(shù)外部的任何地方被訪問到袱讹。
雖然省略 var 操作符可以定義全局變量,但這也不是我們推薦的做法昵时。因為在局 部作用域中定義的全局變量很難維護捷雕,而且如果有意地忽略了 var 操作符,也會由于 相應(yīng)變量不會馬上就有定義而導(dǎo)致不必要的混亂壹甥。給未經(jīng)聲明的變量賦值在嚴(yán)格模式 下會導(dǎo)致拋出 ReferenceError 錯誤救巷。
可以使用一條語句定義多個變量,只要像下面這樣把每個變量(初始化或不初始化均可)用逗號分 隔開即可:
var message = "hi",
found = false,
age = 29;
這個例子定義并初始化了 3個變量句柠。同樣由于 ECMAScript是松散類型的浦译,因而使用不同類型初始 化變量的操作可以放在一條語句中來完成。雖然代碼里的換行和變量縮進不是必需的溯职,但這樣做可以提 高可讀性精盅。
數(shù)據(jù)類型
ECMAScript中有 5種簡單數(shù)據(jù)類型(也稱為基本數(shù)據(jù)類型):Undefined、Null谜酒、Boolean叹俏、Number 和String。還有1種復(fù)雜數(shù)據(jù)類型——Object僻族,Object 本質(zhì)上是由一組無序的名值對組成的粘驰。ECMAScript 不支持任何創(chuàng)建自定義類型的機制,而所有值終都將是上述 6種數(shù)據(jù)類型之一述么。乍一看晴氨,好像只有 6 種數(shù)據(jù)類型不足以表示所有數(shù)據(jù);但是碉输,由于 ECMAScript數(shù)據(jù)類型具有動態(tài)性籽前,因此的確沒有再定義 其他數(shù)據(jù)類型的必要了。
typeof操作符
鑒于 ECMAScript 是松散類型的,因此需要有一種手段來檢測給定變量的數(shù)據(jù)類型——typeof 就 是負(fù)責(zé)提供這方面信息的操作符枝哄。對一個值使用 typeof 操作符可能返回下列某個字符串:
- "undefined"——如果這個值未定義肄梨;
- "boolean"——如果這個值是布爾值;
- "string"——如果這個值是字符串挠锥;
- "number"——如果這個值是數(shù)值;
- "object"——如果這個值是對象或 null;
- "function"——如果這個值是函數(shù)众羡。
Undefined類型
Undefined 類型只有一個值,即特殊的 undefined蓖租。在使用 var 聲明變量但未對其加以初始化時粱侣, 這個變量的值就是 undefined,例如:
var message;
alert(message == undefined); //true
Null類型
Null 類型是第二個只有一個值的數(shù)據(jù)類型蓖宦,這個特殊的值是 null齐婴。從邏輯角度來看,null 值表 示一個空對象指針稠茂,而這也正是使用 typeof 操作符檢測 null 值時會返回"object"的原因柠偶,如下面 的例子所示:
var car = null;
alert(typeof car); // "object"
Boolean類型 Boolean 類型是 ECMAScript中使用得多的一種類型,該類型只有兩個字面值:true 和 false睬关。 這兩個值與數(shù)字值不是一回事诱担,因此 true 不一定等于 1,而 false 也不一定等于 0电爹。以下是為變量賦 Boolean 類型值的例子:
var found = true;
var lost = false;
需要注意的是蔫仙,Boolean 類型的字面值 true 和 false 是區(qū)分大小寫的。也就是說丐箩,True 和 False (以及其他的混合大小寫形式)都不是 Boolean 值摇邦,只是標(biāo)識符。 雖然 Boolean 類型的字面值只有兩個雏蛮,但 ECMAScript中所有類型的值都有與這兩個 Boolean 值 等價的值。要將一個值轉(zhuǎn)換為其對應(yīng)的 Boolean 值阱州,可以調(diào)用轉(zhuǎn)型函數(shù) Boolean()挑秉,如下例所示:
var message = "Hello world!";
var messageAsBoolean = Boolean(message);
在這個例子中,字符串 message 被轉(zhuǎn)換成了一個 Boolean 值苔货,該值被保存在 messageAsBoolean 變量中犀概。可以對任何數(shù)據(jù)類型的值調(diào)用 Boolean()函數(shù)夜惭,而且總會返回一個 Boolean 值姻灶。至于返回的 這個值是 true 還是 false,取決于要轉(zhuǎn)換值的數(shù)據(jù)類型及其實際值诈茧。下表給出了各種數(shù)據(jù)類型及其對 應(yīng)的轉(zhuǎn)換規(guī)則产喉。
數(shù)據(jù)類型 | 轉(zhuǎn)換為true的值 | 轉(zhuǎn)換為false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | ""(空字符串) |
Number | 任何非零數(shù)字值(包括無窮大) | 0 和NaN |
Object | 任何對象 | null |
Undefined | n/a① | undefined |
① n/a(或 N/A),是 not applicable的縮寫,意思是“不適用”曾沈。
Number類型
基本的數(shù)值字面量格式是十進制整數(shù)这嚣。
除了以十進制表示外,整數(shù)還可以通過八進制(以 8為基數(shù))或十六進制(以 16 為基數(shù))的字面值 來表示塞俱。其中,八進制字面值的第一位必須是零(0)障涯,然后是八進制數(shù)字序列(0~7)罐旗。如果字面值中的 數(shù)值超出了范圍,那么前導(dǎo)零將被忽略唯蝶,后面的數(shù)值將被當(dāng)作十進制數(shù)值解析九秀。八進制字面量在嚴(yán)格模式下是無效的,會導(dǎo)致支持的 JavaScript引擎拋出錯誤生棍。
十六進制字面值的前兩位必須是 0x颤霎,后跟任何十六進制數(shù)字(0~9 及 A~F)。其中涂滴,字母 A~F 可以大寫友酱,也可以小寫。
鑒于 JavaScript中保存數(shù)值的方式柔纵,可以保存正零(+0)和負(fù)零(-0)缔杉。正零和負(fù)零被認(rèn)為相等
-
浮點數(shù)值
所謂浮點數(shù)值,就是該數(shù)值中必須包含一個小數(shù)點搁料,并且小數(shù)點后面必須至少有一位數(shù)字或详。
var floatNum1 = 1.1;
var floatNum2 = 0.1;
var floatNum3 = .1; // 有效,但不推薦
對于那些極大或極小的數(shù)值郭计,可以用 e表示法(即科學(xué)計數(shù)法)表示的浮點數(shù)值表示霸琴。用 e表示法 表示的數(shù)值等于 e前面的數(shù)值乘以 10的指數(shù)次冪。ECMAScript中 e表示法的格式也是如此昭伸,即前面是 一個數(shù)值(可以是整數(shù)也可以是浮點數(shù))梧乘,中間是一個大寫或小寫的字母 E,后面是 10的冪中的指數(shù)庐杨, 該冪值將用來與前面的數(shù)相乘选调。
浮點數(shù)值的高精度是 17位小數(shù),但在進行算術(shù)計算時其精確度遠遠不如整數(shù)灵份。
-
數(shù)值范圍
由于內(nèi)存的限制仁堪,ECMAScript并不能保存世界上所有的數(shù)值。ECMAScript能夠表示的小數(shù)值保 存在 Number.MIN_VALUE 中——在大多數(shù)瀏覽器中填渠,這個值是 5e-324弦聂;能夠表示的大數(shù)值保存在 Number.MAX_VALUE 中——在大多數(shù)瀏覽器中鸟辅,這個值是 1.7976931348623157e+308。如果某次計算的 結(jié)果得到了一個超出 JavaScript數(shù)值范圍的值横浑,那么這個數(shù)值將被自動轉(zhuǎn)換成特殊的 Infinity 值剔桨。具 體來說,如果這個數(shù)值是負(fù)數(shù)徙融,則會被轉(zhuǎn)換成-Infinity(負(fù)無窮)洒缀,如果這個數(shù)值是正數(shù),則會被轉(zhuǎn) 換成 Infinity(正無窮)欺冀。
如上所述树绩,如果某次計算返回了正或負(fù)的 Infinity 值,那么該值將無法繼續(xù)參與下一次的計算隐轩, 因為 Infinity 不是能夠參與計算的數(shù)值饺饭。
-
NaN
NaN,即非數(shù)值(Not a Number)是一個特殊的數(shù)值职车,這個數(shù)值用于表示一個本來要返回數(shù)值的操作數(shù) 未返回數(shù)值的情況(這樣就不會拋出錯誤了)瘫俊。例如,在其他編程語言中悴灵,任何數(shù)值除以 0都會導(dǎo)致錯誤扛芽, 從而停止代碼執(zhí)行。但在ECMAScript中积瞒,任何數(shù)值除以 0會返回 NaN川尖,因此不會影響其他代碼的執(zhí)行。 NaN 本身有兩個非同尋常的特點茫孔。首先叮喳,任何涉及 NaN 的操作(例如 NaN/10)都會返回 NaN,這 個特點在多步計算中有可能導(dǎo)致問題缰贝。其次馍悟,NaN 與任何值都不相等,包括 NaN 本身剩晴。
針對 NaN 的這兩個特點锣咒,ECMAScript定義了 isNaN()函數(shù)。這個函數(shù)接受一個參數(shù)李破,該參數(shù)可以 是任何類型宠哄,而函數(shù)會幫我們確定這個參數(shù)是否“不是數(shù)值”壹将。
- 數(shù)值轉(zhuǎn)換
有 3個函數(shù)可以把非數(shù)值轉(zhuǎn)換為數(shù)值:Number()嗤攻、parseInt()和 parseFloat()。第一個函數(shù)诽俯, 即轉(zhuǎn)型函數(shù) Number()可以用于任何數(shù)據(jù)類型妇菱,而另兩個函數(shù)則專門用于把字符串轉(zhuǎn)換成數(shù)值承粤。這 3個 函數(shù)對于同樣的輸入會有返回不同的結(jié)果。 Number()函數(shù)的轉(zhuǎn)換規(guī)則如下闯团。
如果是 Boolean 值辛臊,true 和 false 將分別被轉(zhuǎn)換為 1和 0。
如果是數(shù)字值房交,只是簡單的傳入和返回彻舰。
如果是 null 值,返回 0候味。
如果是 undefined刃唤,返回 NaN。
-
如果是字符串白群,遵循下列規(guī)則:
- 如果字符串中只包含數(shù)字(包括前面帶正號或負(fù)號的情況)尚胞,則將其轉(zhuǎn)換為十進制數(shù)值,即"1" 會變成 1帜慢,"123"會變成 123笼裳,而"011"會變成 11(注意:前導(dǎo)的零被忽略了);
- 如果字符串中包含有效的浮點格式粱玲,如"1.1"躬柬,則將其轉(zhuǎn)換為對應(yīng)的浮點數(shù)值(同樣,也會忽 略前導(dǎo)零)密幔;
- 如果字符串中包含有效的十六進制格式楔脯,例如"0xf",則將其轉(zhuǎn)換為相同大小的十進制整 數(shù)值;
- 如果字符串是空的(不包含任何字符),則將其轉(zhuǎn)換為 0砸紊;
- 如果字符串中包含除上述格式之外的字符啤覆,則將其轉(zhuǎn)換為 NaN。
如果是對象锐朴,則調(diào)用對象的 valueOf()方法,然后依照前面的規(guī)則轉(zhuǎn)換返回的值。如果轉(zhuǎn)換 的結(jié)果是 NaN眉枕,則調(diào)用對象的 toString()方法,然后再次依照前面的規(guī)則轉(zhuǎn)換返回的字符 串值怜森。
parseInt()函數(shù)在轉(zhuǎn)換字符串時速挑,更多的是看其是否符合數(shù)值模式。它會忽略字 符串前面的空格副硅,直至找到第一個非空格字符姥宝。如果第一個字符不是數(shù)字字符或者負(fù)號,parseInt() 就會返回 NaN恐疲;也就是說腊满,用 parseInt()轉(zhuǎn)換空字符串會返回 NaN(Number()對空字符返回 0)套么。如 果第一個字符是數(shù)字字符,parseInt()會繼續(xù)解析第二個字符碳蛋,直到解析完所有后續(xù)字符或者遇到了 一個非數(shù)字字符胚泌。
與 parseInt()函數(shù)類似,parseFloat()也是從第一個字符(位置 0)開始解析每個字符肃弟。而且 也是一直解析到字符串末尾玷室,或者解析到遇見一個無效的浮點數(shù)字字符為止。也就是說笤受,字符串中的第 一個小數(shù)點是有效的阵苇,而第二個小數(shù)點就是無效的了,因此它后面的字符串將被忽略感论。
String類型
- 字符字面量
String 數(shù)據(jù)類型包含一些特殊的字符字面量绅项,也叫轉(zhuǎn)義序列,用于表示非打印字符比肄,或者具有其 他用途的字符快耿。這些字符字面量如下表所示:
字 面 量 | 含 義 |
---|---|
\n | 換行 |
\t | 制表 |
\b | 空格 |
\r | 回車 |
\f | 進紙 |
\ \ | 斜杠 |
\ ' | 單引號('),在用單引號表示的字符串中使用芳绩。例如:'He said, \ 'hey.\ ' ' |
\ " | 雙引號(")掀亥,在用雙引號表示的字符串中使用。例如:"He said, \ "hey.\ " " |
\xnn | 以十六進制代碼nn表示的一個字符(其中n為0~F)妥色。例如搪花,\x41表示"A" |
\unnnn | 以十六進制代碼nnnn表示的一個Unicode字符(其中n為0~F)。例如嘹害,\u03a3表示希臘字符Σ |
- 轉(zhuǎn)換為字符串
要把一個值轉(zhuǎn)換為一個字符串有兩種方式撮竿。第一種是使用幾乎每個值都有的 toString()方法。
在不知道要轉(zhuǎn)換的值是不是 null 或 undefined 的情況下笔呀,還可以使用轉(zhuǎn)型函數(shù) String()幢踏,這個 函數(shù)能夠?qū)⑷魏晤愋偷闹缔D(zhuǎn)換為字符串。String()函數(shù)遵循下列轉(zhuǎn)換規(guī)則:
- 如果值有 toString()方法许师,則調(diào)用該方法(沒有參數(shù))并返回相應(yīng)的結(jié)果房蝉;
- 如果值是 null,則返回"null"微渠;
- 如果值是 undefined搭幻,則返回"undefined"。
Object類型
ECMAScript中的對象其實就是一組數(shù)據(jù)和功能的集合逞盆。對象可以通過執(zhí)行 new 操作符后跟要創(chuàng)建 的對象類型的名稱來創(chuàng)建檀蹋。而創(chuàng)建 Object 類型的實例并為其添加屬性和(或)方法,就可以創(chuàng)建自定 義對象纳击,如下所示:
var o = new Object();
Object 類型是所有它的實例的基礎(chǔ)续扔。換句話說, Object 類型所具有的任何屬性和方法也同樣存在于更具體的對象中焕数。 Object 的每個實例都具有下列屬性和方法纱昧。
- constructor:保存著用于創(chuàng)建當(dāng)前對象的函數(shù)。對于前面的例子而言堡赔,構(gòu)造函數(shù)(constructor) 就是 Object()识脆。
- hasOwnProperty(propertyName):用于檢查給定的屬性在當(dāng)前對象實例中(而不是在實例 的原型中)是否存在。其中善已,作為參數(shù)的屬性名(propertyName)必須以字符串形式指定(例 如:o.hasOwnProperty("name"))灼捂。
- isPrototypeOf(object):用于檢查傳入的對象是否是傳入對象的原型(第 5 章將討論原 型) 。
- propertyIsEnumerable(propertyName):用于檢查給定的屬性是否能夠使用 for-in 語句 (本章后面將會討論)來枚舉换团。與 hasOwnProperty()方法一樣悉稠,作為參數(shù)的屬性名必須以字符 串形式指定。
- toLocaleString():返回對象的字符串表示艘包,該字符串與執(zhí)行環(huán)境的地區(qū)對應(yīng)的猛。
- toString():返回對象的字符串表示。 ? valueOf():返回對象的字符串想虎、數(shù)值或布爾值表示卦尊。通常與 toString()方法的返回值 相同。
操作符
ECMA-262 描述了一組用于操作數(shù)據(jù)值的操作符舌厨,包括算術(shù)操作符(如加號和減號)岂却、位操作符、 關(guān)系操作符和相等操作符裙椭。ECMAScript 操作符的與眾不同之處在于躏哩,它們能夠適用于很多值,例如字 符串揉燃、數(shù)字值震庭、布爾值,甚至對象你雌。不過器联,在應(yīng)用于對象時,相應(yīng)的操作符通常都會調(diào)用對象的 valueOf() 和(或)toString()方法婿崭,以便取得可以操作的值拨拓。
一元操作符
1. 遞增和遞減操作符 ++age; --age;
- 在應(yīng)用于一個包含有效數(shù)字字符的字符串時,先將其轉(zhuǎn)換為數(shù)字值氓栈,再執(zhí)行加減 1 的操作渣磷。字 符串變量變成數(shù)值變量。
- 在應(yīng)用于一個不包含有效數(shù)字字符的字符串時授瘦,將變量的值設(shè)置為 NaN(第 4章將詳細(xì)討論)醋界。 字符串變量變成數(shù)值變量竟宋。
- 在應(yīng)用于布爾值 false 時,先將其轉(zhuǎn)換為 0再執(zhí)行加減 1的操作形纺。布爾值變量變成數(shù)值變量丘侠。
- 在應(yīng)用于布爾值 true 時,先將其轉(zhuǎn)換為 1再執(zhí)行加減 1的操作逐样。布爾值變量變成數(shù)值變量蜗字。
- 在應(yīng)用于浮點數(shù)值時,執(zhí)行加減 1的操作脂新。
- 在應(yīng)用于對象時挪捕,先調(diào)用對象的 valueOf()方法以取得一個可供操作的 值。然后對該值應(yīng)用前述規(guī)則争便。如果結(jié)果是 NaN级零,則在調(diào)用 toString()方法后再應(yīng)用前述規(guī) 則。對象變量變成數(shù)值變量滞乙。
2. 一元加和減操作符 + -
位操作符
按位非(NOT) ~
按位與(AND) &
按位或(OR) |
按位異或(XOR) ^
左移 <<
有符號的右移 >>
無符號右移 >>>
布爾操作符
-
邏輯非
邏輯非操作符由一個嘆號(M丁)表示,可以應(yīng)用于 ECMAScript中的任何值酷宵。無論這個值是什么數(shù)據(jù) 類型亥贸,這個操作符都會返回一個布爾值。邏輯非操作符首先會將它的操作數(shù)轉(zhuǎn)換為一個布爾值浇垦,然后再 對其求反炕置。也就是說,邏輯非操作符遵循下列規(guī)則:
- 如果操作數(shù)是一個對象男韧,返回 false朴摊;
- 如果操作數(shù)是一個空字符串,返回 true此虑;
- 如果操作數(shù)是一個非空字符串甚纲,返回 false;
- 如果操作數(shù)是數(shù)值 0朦前,返回 true介杆;
- 如果操作數(shù)是任意非 0數(shù)值(包括 Infinity),返回 false韭寸;
- 如果操作數(shù)是 null春哨,返回 true;
- 如果操作數(shù)是 NaN恩伺,返回 true赴背;
- 如果操作數(shù)是 undefined,返回 true。
-
邏輯與
邏輯與操作符由兩個和號(&&)表示凰荚,有兩個操作數(shù)
邏輯與操作可以應(yīng)用于任何類型的操作數(shù)燃观,而不僅僅是布爾值。在有一個操作數(shù)不是布爾值的情況 下便瑟,邏輯與操作就不一定返回布爾值缆毁;此時,它遵循下列規(guī)則:
- 如果第一個操作數(shù)是對象胳徽,則返回第二個操作數(shù);
- 如果第二個操作數(shù)是對象爽彤,則只有在第一個操作數(shù)的求值結(jié)果為 true 的情況下才會返回該 對象养盗;
- 如果兩個操作數(shù)都是對象,則返回第二個操作數(shù)适篙;
- 如果有一個操作數(shù)是 null往核,則返回 null;
- 如果有一個操作數(shù)是 NaN嚷节,則返回 NaN聂儒;
- 如果有一個操作數(shù)是 undefined,則返回 undefined硫痰。
-
邏輯或
邏輯或操作符由兩個豎線符號(||)表示衩婚,有兩個操作數(shù)
與邏輯與操作相似,如果有一個操作數(shù)不是布爾值效斑,邏輯或也不一定返回布爾值非春;此時,它遵循下 列規(guī)則:
- 如果第一個操作數(shù)是對象缓屠,則返回第一個操作數(shù)奇昙;
- 如果第一個操作數(shù)的求值結(jié)果為 false,則返回第二個操作數(shù)敌完;
- 如果兩個操作數(shù)都是對象储耐,則返回第一個操作數(shù);
- 如果兩個操作數(shù)都是 null滨溉,則返回 null什湘;
- 如果兩個操作數(shù)都是 NaN,則返回 NaN晦攒;
- 如果兩個操作數(shù)都是 undefined禽炬,則返回 undefined。
乘性操作符
-
乘法
乘法操作符由一個星號(*)表示勤家,用于計算兩個數(shù)值的乘積腹尖。
在處理特殊值的情況下,乘法操作符遵循下列特殊的規(guī)則:
- 如果操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的乘法計算热幔,即兩個正數(shù)或兩個負(fù)數(shù)相乘的結(jié)果還是正數(shù)乐设,而 如果只有一個操作數(shù)有符號,那么結(jié)果就是負(fù)數(shù)绎巨。如果乘積超過了 ECMAScript數(shù)值的表示范圍近尚, 則返回 Infinity 或-Infinity;
- 如果有一個操作數(shù)是 NaN场勤,則結(jié)果是 NaN戈锻;
- 如果是 Infinity 與 0相乘,則結(jié)果是 NaN和媳;
- 如果是 Infinity 與非 0數(shù)值相乘格遭,則結(jié)果是 Infinity 或-Infinity,取決于有符號操作數(shù) 的符號留瞳;
- 如果是 Infinity 與 Infinity 相乘拒迅,則結(jié)果是 Infinity;
- 如果有一個操作數(shù)不是數(shù)值她倘,則在后臺調(diào)用 Number()將其轉(zhuǎn)換為數(shù)值璧微,然后再應(yīng)用上面的 規(guī)則。
-
除法
除法操作符由一個斜線符號(/)表示硬梁,執(zhí)行第二個操作數(shù)除第一個操作數(shù)的計算 與乘法操作符類似前硫,除法操作符對特殊的值也有特殊的處理規(guī)則。這些規(guī)則如下:
- 如果操作數(shù)都是數(shù)值荧止,執(zhí)行常規(guī)的除法計算开瞭,即兩個正數(shù)或兩個負(fù)數(shù)相除的結(jié)果還是正數(shù),而 如果只有一個操作數(shù)有符號罩息,那么結(jié)果就是負(fù)數(shù)嗤详。如果商超過了 ECMAScript數(shù)值的表示范圍, 則返回 Infinity 或-Infinity瓷炮;
- 如果有一個操作數(shù)是 NaN葱色,則結(jié)果是 NaN;
- 如果是 Infinity 被 Infinity 除娘香,則結(jié)果是 NaN苍狰;
- 如果是零被零除,則結(jié)果是 NaN烘绽;
- 如果是非零的有限數(shù)被零除淋昭,則結(jié)果是 Infinity 或-Infinity,取決于有符號操作數(shù)的符號安接;
- 如果是 Infinity 被任何非零數(shù)值除翔忽,則結(jié)果是 Infinity 或-Infinity,取決于有符號操作 數(shù)的符號;
- 如果有一個操作數(shù)不是數(shù)值歇式,則在后臺調(diào)用 Number()將其轉(zhuǎn)換為數(shù)值驶悟,然后再應(yīng)用上面的規(guī)則。
-
求模
求模(余數(shù))操作符由一個百分號(%)表示
與另外兩個乘性操作符類似材失,求模操作符會遵循下列特殊規(guī)則來處理特殊的值:
- 如果操作數(shù)都是數(shù)值痕鳍,執(zhí)行常規(guī)的除法計算,返回除得的余數(shù)龙巨;
- 如果被除數(shù)是無窮大值而除數(shù)是有限大的數(shù)值笼呆,則結(jié)果是 NaN;
- 如果被除數(shù)是有限大的數(shù)值而除數(shù)是零旨别,則結(jié)果是 NaN诗赌;
- 如果是 Infinity 被 Infinity 除,則結(jié)果是 NaN昼榛;
- 如果被除數(shù)是有限大的數(shù)值而除數(shù)是無窮大的數(shù)值境肾,則結(jié)果是被除數(shù)剔难;
- 如果被除數(shù)是零胆屿,則結(jié)果是零;
- 如果有一個操作數(shù)不是數(shù)值偶宫,則在后臺調(diào)用 Number()將其轉(zhuǎn)換為數(shù)值非迹,然后再應(yīng)用上面的規(guī)則。
加性操作符
加法和減法這兩個加性操作符應(yīng)該說是編程語言中簡單的算術(shù)操作符了纯趋。但是在 ECMAScript中憎兽, 這兩個操作符卻都有一系列的特殊行為。與乘性操作符類似吵冒,加性操作符也會在后臺轉(zhuǎn)換不同的數(shù)據(jù)類 型纯命。然而,對于加性操作符而言痹栖,相應(yīng)的轉(zhuǎn)換規(guī)則還稍微有點復(fù)雜亿汞。
-
加法
加法操作符(+)
如果兩個操作符都是數(shù)值,執(zhí)行常規(guī)的加法計算揪阿,然后根據(jù)下列規(guī)則返回結(jié)果:
- 如果有一個操作數(shù)是 NaN疗我,則結(jié)果是 NaN;
- 如果是 Infinity 加 Infinity南捂,則結(jié)果是 Infinity吴裤;
- 如果是-Infinity 加-Infinity,則結(jié)果是-Infinity溺健;
- 如果是 Infinity 加-Infinity麦牺,則結(jié)果是 NaN;
- 如果是+0加+0,則結(jié)果是+0枕面;
- 如果是-0加-0愿卒,則結(jié)果是-0;
- 如果是+0加-0潮秘,則結(jié)果是+0琼开。
不過,如果有一個操作數(shù)是字符串枕荞,那么就要應(yīng)用如下規(guī)則:
- 如果兩個操作數(shù)都是字符串柜候,則將第二個操作數(shù)與第一個操作數(shù)拼接起來;
- 如果只有一個操作數(shù)是字符串躏精,則將另一個操作數(shù)轉(zhuǎn)換為字符串渣刷,然后再將兩個字符串拼接 起來。
如果有一個操作數(shù)是對象矗烛、數(shù)值或布爾值辅柴,則調(diào)用它們的 toString()方法取得相應(yīng)的字符串值, 然后再應(yīng)用前面關(guān)于字符串的規(guī)則瞭吃。對于 undefined 和 null碌嘀,則分別調(diào)用 String()函數(shù)并取得字符 串"undefined"和"null"。 以上代碼演示了加法操作符在兩種模式下的差別歪架。第一行代碼演示了正常的情況股冗,即 5+5 等于 10 (數(shù)值)。但是和蚪,如果將一個操作數(shù)改為字符串"5"止状,結(jié)果就變成了"55"(字符串值),因為第一個操作 數(shù)也被轉(zhuǎn)換成了"5"攒霹。 忽視加法操作中的數(shù)據(jù)類型是 ECMAScript編程中常見的一個錯誤怯疤。
-
減法
減法操作符(-)是另一個極為常用的操作符
與加法操作符類似,ECMAScript 中的減法操作符在處理各種數(shù)據(jù)類型轉(zhuǎn)換時催束,同樣需要遵循一些 特殊規(guī)則集峦,如下所示:
- 如果兩個操作符都是數(shù)值,則執(zhí)行常規(guī)的算術(shù)減法操作并返回結(jié)果泣崩;
- 如果有一個操作數(shù)是 NaN少梁,則結(jié)果是 NaN;
- 如果是 Infinity 減 Infinity矫付,則結(jié)果是 NaN凯沪;
- 如果是-Infinity 減-Infinity,則結(jié)果是 NaN买优;
- 如果是 Infinity 減-Infinity妨马,則結(jié)果是 Infinity挺举;
- 如果是-Infinity 減 Infinity,則結(jié)果是-Infinity烘跺;
- 如果是+0減+0湘纵,則結(jié)果是+0;
- 如果是+0減-0滤淳,則結(jié)果是-0梧喷;
- 如果是-0減-0,則結(jié)果是+0脖咐;
- 如果有一個操作數(shù)是字符串铺敌、布爾值、null 或 undefined屁擅,則先在后臺調(diào)用 Number()函數(shù)將 其轉(zhuǎn)換為數(shù)值偿凭,然后再根據(jù)前面的規(guī)則執(zhí)行減法計算。如果轉(zhuǎn)換的結(jié)果是 NaN派歌,則減法的結(jié)果 就是 NaN弯囊;
- 如果有一個操作數(shù)是對象,則調(diào)用對象的 valueOf()方法以取得表示該對象的數(shù)值胶果。如果得到 的值是 NaN匾嘱,則減法的結(jié)果就是 NaN。如果對象沒有 valueOf()方法稽物,則調(diào)用其 toString() 方法并將得到的字符串轉(zhuǎn)換為數(shù)值奄毡。
關(guān)系操作符
小于(<)折欠、大于(>)贝或、小于等于(<=)和大于等于(>=)
與 ECMAScript中的其他操作符一樣,當(dāng)關(guān)系操作符的操作數(shù)使用了非數(shù)值時锐秦,也要進行數(shù)據(jù)轉(zhuǎn)換 或完成某些奇怪的操作咪奖。以下就是相應(yīng)的規(guī)則。
- 如果兩個操作數(shù)都是數(shù)值酱床,則執(zhí)行數(shù)值比較羊赵。
- 如果兩個操作數(shù)都是字符串,則比較兩個字符串對應(yīng)的字符編碼值扇谣。
- 如果一個操作數(shù)是數(shù)值昧捷,則將另一個操作數(shù)轉(zhuǎn)換為一個數(shù)值,然后執(zhí)行數(shù)值比較罐寨。
- 如果一個操作數(shù)是對象靡挥,則調(diào)用這個對象的 valueOf()方法,用得到的結(jié)果按照前面的規(guī)則執(zhí) 行比較鸯绿。如果對象沒有 valueOf()方法跋破,則調(diào)用 toString()方法簸淀,并用得到的結(jié)果根據(jù)前面 的規(guī)則執(zhí)行比較。
- 如果一個操作數(shù)是布爾值毒返,則先將其轉(zhuǎn)換為數(shù)值租幕,然后再執(zhí)行比較。
相等操作符
確定兩個變量是否相等是編程中的一個非常重要的操作拧簸。在比較字符串劲绪、數(shù)值和布爾值的相等性時, 問題還比較簡單盆赤。但在涉及到對象的比較時珠叔,問題就變得復(fù)雜了。早的 ECMAScript中的相等和不等 操作符會在執(zhí)行比較之前弟劲,先將對象轉(zhuǎn)換成相似的類型祷安。后來,有人提出了這種轉(zhuǎn)換到底是否合理的質(zhì) 疑兔乞。后汇鞭,ECMAScript 的解決方案就是提供兩組操作符:相等和不相等——先轉(zhuǎn)換再比較,全等和不 全等——僅比較而不轉(zhuǎn)換庸追。
-
相等和不相等
ECMAScript中的相等操作符由兩個等于號(==)表示霍骄,如果兩個操作數(shù)相等,則返回 true淡溯。而不 相等操作符由嘆號后跟等于號(!=)表示读整,如果兩個操作數(shù)不相等,則返回 true咱娶。這兩個操作符都會 先轉(zhuǎn)換操作數(shù)(通常稱為強制轉(zhuǎn)型)米间,然后再比較它們的相等性。 在轉(zhuǎn)換不同的數(shù)據(jù)類型時膘侮,相等和不相等操作符遵循下列基本規(guī)則:
- 如果有一個操作數(shù)是布爾值屈糊,則在比較相等性之前先將其轉(zhuǎn)換為數(shù)值——false 轉(zhuǎn)換為 0,而 true 轉(zhuǎn)換為 1琼了;
- 如果一個操作數(shù)是字符串逻锐,另一個操作數(shù)是數(shù)值,在比較相等性之前先將字符串轉(zhuǎn)換為數(shù)值雕薪;
- 如果一個操作數(shù)是對象昧诱,另一個操作數(shù)不是,則調(diào)用對象的 valueOf()方法所袁,用得到的基本類 型值按照前面的規(guī)則進行比較盏档; 這兩個操作符在進行比較時則要遵循下列規(guī)則。
- null 和 undefined 是相等的纲熏。
- 要比較相等性之前妆丘,不能將 null 和 undefined 轉(zhuǎn)換成其他任何值锄俄。
- 如果有一個操作數(shù)是 NaN,則相等操作符返回 false勺拣,而不相等操作符返回 true奶赠。重要提示: 即使兩個操作數(shù)都是 NaN,相等操作符也返回 false药有;因為按照規(guī)則毅戈,NaN 不等于 NaN。
- 如果兩個操作數(shù)都是對象愤惰,則比較它們是不是同一個對象苇经。如果兩個操作數(shù)都指向同一個對象, 則相等操作符返回 true宦言;否則扇单,返回 false。
-
全等和不全等
除了在比較之前不轉(zhuǎn)換操作數(shù)之外奠旺,全等和不全等操作符與相等和不相等操作符沒有什么區(qū)別蜘澜。全 等操作符由 3個等于號(===)表示,它只在兩個操作數(shù)未經(jīng)轉(zhuǎn)換就相等的情況下返回 true响疚。
由于相等和不相等操作符存在類型轉(zhuǎn)換問題鄙信,而為了保持代碼中數(shù)據(jù)類型的完整 性,我們推薦使用全等和不全等操作符忿晕。
條件操作符
條件操作符應(yīng)該算是 ECMAScript中靈活的一種操作符了装诡,而且它遵循與 Java中的條件操作符相 同的語法形式,如下面的例子所示:
variable = boolean_expression ? true_value : false_value;
賦值操作符
簡單的賦值操作符由等于號(=)表示践盼,其作用就是把右側(cè)的值賦給左側(cè)的變量
每個主要算術(shù)操作符(以及個別的其他操作符)都有對應(yīng)的復(fù)合賦值操作符鸦采。這些操作符如下所示:
- 乘/賦值(*=);
- 除/賦值(/=)宏侍;
- 模/賦值(%=)赖淤;
- 加/賦值(+=)蜀漆;
- 減/賦值(-=)谅河;
- 左移/賦值(<<=);
- 有符號右移/賦值(>>=)确丢;
- 無符號右移/賦值(>>>=)绷耍。
設(shè)計這些操作符的主要目的就是簡化賦值操作。使用它們不會帶來任何性能的提升鲜侥。
逗號操作符
使用逗號操作符可以在一條語句中執(zhí)行多個操作
語句
1.if語句
大多數(shù)編程語言中為常用的一個語句就是 if 語句褂始。以下是 if 語句的語法:
if (condition) statement1 else statement2
其中的 condition(條件)可以是任意表達式;而且對這個表達式求值的結(jié)果不一定是布爾值描函。 ECMAScript會自動調(diào)用 Boolean()轉(zhuǎn)換函數(shù)將這個表達式的結(jié)果轉(zhuǎn)換為一個布爾值崎苗。如果對 condition 求值的結(jié)果是true狐粱,則執(zhí)行statement1(語句1),如果對condition求值的結(jié)果是false胆数,則執(zhí)行statement2 (語句 2)肌蜻。而且這兩個語句既可以是一行代碼,也可以是一個代碼塊(以一對花括號括起來的多行代碼)必尼。
2.do-while語句
do-while 語句是一種后測試循環(huán)語句蒋搜,即只有在循環(huán)體中的代碼執(zhí)行之后,才會測試出口條件判莉。 換句話說豆挽,在對條件表達式求值之前,循環(huán)體內(nèi)的代碼至少會被執(zhí)行一次券盅。以下是 do-while 語句的 語法:
do {
statement
} while (expression);
3.while語句
while 語句屬于前測試循環(huán)語句帮哈,也就是說,在循環(huán)體內(nèi)的代碼被執(zhí)行之前锰镀,就會對出口條件求值但汞。 因此,循環(huán)體內(nèi)的代碼有可能永遠不會被執(zhí)行互站。以下是 while 語句的語法:
while(expression) statement
4.for語句
for 語句也是一種前測試循環(huán)語句私蕾,但它具有在執(zhí)行循環(huán)之前初始化變量和定義循環(huán)后要執(zhí)行的代 碼的能力。以下是 for 語句的語法:
for (initialization; expression; post-loop-expression) statement
5.for-in語句
for-in 語句是一種精準(zhǔn)的迭代語句胡桃,可以用來枚舉對象的屬性踩叭。以下是 for-in 語句的語法:
for (property in expression) statement
下面是一個示例:
for (var propName in window) {
document.write(propName);
}
在這個例子中,我們使用 for-in 循環(huán)來顯示了 BOM中 window 對象的所有屬性翠胰。每次執(zhí)行循環(huán) 時容贝,都會將 window 對象中存在的一個屬性名賦值給變量 propName。這個過程會一直持續(xù)到對象中的 所有屬性都被枚舉一遍為止之景。與 for 語句類似斤富,這里控制語句中的 var 操作符也不是必需的。但是锻狗, 為了保證使用局部變量满力,我們推薦上面例子中的這種做法。
ECMAScript 對象的屬性沒有順序轻纪。因此油额,通過 for-in 循環(huán)輸出的屬性名的順序是不可預(yù)測的。 具體來講刻帚,所有屬性都會被返回一次潦嘶,但返回的先后次序可能會因瀏覽器而異。
但是崇众,如果表示要迭代的對象的變量值為 null 或 undefined掂僵,for-in 語句會拋出錯誤航厚。 ECMAScript 5更正了這一行為;對這種情況不再拋出錯誤锰蓬,而只是不執(zhí)行循環(huán)體阶淘。為了保證大限度的兼容性,建議在使用 for-in 循環(huán)之前互妓,先檢測確認(rèn)該對象的值不是 null 或 undefined溪窒。
6.label語句
使用 label 語句可以在代碼中添加標(biāo)簽,以便將來使用冯勉。以下是 label 語句的語法:
label: statement
下面是一個示例:
start: for (var i=0; i < count; i++) {
alert(i);
}
這個例子中定義的 start 標(biāo)簽可以在將來由 break 或 continue 語句引用澈蚌。加標(biāo)簽的語句一般都 要與 for 語句等循環(huán)語句配合使用。
7.break和continue語句
break 和 continue 語句用于在循環(huán)中精確地控制代碼的執(zhí)行灼狰。其中宛瞄,break 語句會立即退出循環(huán), 強制繼續(xù)執(zhí)行循環(huán)后面的語句交胚。而 continue 語句雖然也是立即退出循環(huán)份汗,但退出循環(huán)后會從循環(huán)的頂 部繼續(xù)執(zhí)行。
8.with語句
with 語句的作用是將代碼的作用域設(shè)置到一個特定的對象中蝴簇。with 語句的語法如下:
with (expression) statement;
定義 with 語句的目的主要是為了簡化多次編寫同一個對象的工作杯活,如下面的例子所示:
var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;
上面幾行代碼都包含 location 對象。如果使用 with 語句熬词,可以把上面的代碼改寫成如下所示:
with(location){
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}
WithStatementExample01.htm
在這個重寫后的例子中旁钧,使用 with 語句關(guān)聯(lián)了 location 對象。這意味著在 with 語句的代碼塊 內(nèi)部互拾,每個變量首先被認(rèn)為是一個局部變量歪今,而如果在局部環(huán)境中找不到該變量的定義,就會查詢 location 對象中是否有同名的屬性颜矿。如果發(fā)現(xiàn)了同名屬性寄猩,則以 location 對象屬性的值作為變量的值。
嚴(yán)格模式下不允許使用 with 語句骑疆,否則將視為語法錯誤田篇。
9.switch語句
switch 語句與 if 語句的關(guān)系為密切,而且也是在其他語言中普遍使用的一種流控制語句封断。 ECMAScript中 switch 語句的語法與其他基于 C的語言非常接近斯辰,如下所示:
switch (expression) {
case value: statement
break;
case value: statement
break;
case value: statement
break;
case value: statement
break;
default: statement
}
函數(shù)
函數(shù)對任何語言來說都是一個核心的概念。通過函數(shù)可以封裝任意多條語句坡疼,而且可以在任何地方、 任何時候調(diào)用執(zhí)行衣陶。ECMAScript中的函數(shù)使用 function 關(guān)鍵字來聲明柄瑰,后跟一組參數(shù)以及函數(shù)體闸氮。 函數(shù)的基本語法如下所示:
function functionName(arg0, arg1,...,argN) { statements }
嚴(yán)格模式對函數(shù)有一些限制:
- 不能把函數(shù)命名為 eval 或 arguments;
- 不能把參數(shù)命名為 eval 或 arguments教沾;
- 不能出現(xiàn)兩個命名參數(shù)同名的情況蒲跨。
如果發(fā)生以上情況,就會導(dǎo)致語法錯誤授翻,代碼無法執(zhí)行或悲。
參數(shù)
ECMAScript函數(shù)的參數(shù)與大多數(shù)其他語言中函數(shù)的參數(shù)有所不同。ECMAScript函數(shù)不介意傳遞進 來多少個參數(shù)堪唐,也不在乎傳進來參數(shù)是什么數(shù)據(jù)類型巡语。也就是說,即便你定義的函數(shù)只接收兩個參數(shù)淮菠, 在調(diào)用這個函數(shù)時也未必一定要傳遞兩個參數(shù)男公。可以傳遞一個合陵、三個甚至不傳遞參數(shù)枢赔,而解析器永遠不 會有什么怨言。之所以會這樣拥知,原因是 ECMAScript中的參數(shù)在內(nèi)部是用一個數(shù)組來表示的整份。函數(shù)接收 到的始終都是這個數(shù)組,而不關(guān)心數(shù)組中包含哪些參數(shù)(如果有參數(shù)的話)秒裕。如果這個數(shù)組中不包含任 何元素忌愚,無所謂;如果包含多個元素户侥,也沒有問題镀琉。實際上,在函數(shù)體內(nèi)可以通過 arguments 對象來 訪問這個參數(shù)數(shù)組蕊唐,從而獲取傳遞給函數(shù)的每一個參數(shù)屋摔。
嚴(yán)格模式對如何使用 arguments 對象做出了一些限制。首先替梨,像前面例子中那樣的賦值會變得無 效钓试。也就是說,即使把 arguments[1]設(shè)置為 10副瀑,num2 的值仍然還是 undefined弓熏。其次,重寫 arguments 的值會導(dǎo)致語法錯誤(代碼將不會執(zhí)行)糠睡。
ECMAScript中的所有參數(shù)傳遞的都是值挽鞠,不可能通過引用傳遞參數(shù)。
沒有重載
ECMAScript 函數(shù)不能像傳統(tǒng)意義上那樣實現(xiàn)重載。而在其他語言(如 Java)中信认,可以為一個函數(shù) 編寫兩個定義材义,只要這兩個定義的簽名(接受的參數(shù)的類型和數(shù)量)不同即可。如前所述嫁赏,ECMAScirpt 函數(shù)沒有簽名其掂,因為其參數(shù)是由包含零或多個值的數(shù)組來表示的。而沒有函數(shù)簽名潦蝇,真正的重載是不可 能做到的款熬。
如果在 ECMAScript中定義了兩個名字相同的函數(shù),則該名字只屬于后定義的函數(shù)攘乒。