1、標(biāo)識(shí)符
標(biāo)識(shí)符是指變量、函數(shù)、屬性的名字,或函數(shù)的參數(shù)。
格式規(guī)則:
- 第一個(gè)字符必須是一個(gè)字母、下劃線(_)或一個(gè)美元符號(hào)($)。
- 其他字符可以是字母、下劃線、美元符號(hào)或數(shù)字。
- 不能把關(guān)鍵字、保留字、true、false、和 null 用作標(biāo)識(shí)符。
- 最好采用駝峰大小寫格式。
2、關(guān)鍵字
關(guān)鍵字用途:
- 用于表示控制語句的開始或結(jié)束。
- 用于執(zhí)行特定操作等。
關(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 let
delete in try yield
3、變量
??ECMAScript 的變量時(shí)松散類型的,所謂松散類型就是可以用來保存任何類型的數(shù)據(jù)。
??初始化變量:給變量賦值。
可以在修改量值的同時(shí)修改值的類型,但不推薦。
4、數(shù)據(jù)類型
5 種簡單數(shù)據(jù)類型(基本數(shù)據(jù)類型):
- Undefined — undefined
- Null — null
- Boolean — true ,false
- Number
- String
1 種復(fù)雜數(shù)據(jù)類型 —— Object:本質(zhì)上是由一組無序的名值對(duì)組成的。
4.1、typeof 操作符
??因?yàn)?ECMAScript 是松散類型的,所以需要一種手段來檢測給定變量的數(shù)據(jù)類型 —— typeof就是用來檢測變量數(shù)據(jù)類型的操作符。
typeof 操作符的返回值:
- "undefined" —— 這個(gè)值未定義
- "boolean" —— 是布爾值
- "string" —— 是字符串
- "number" —— 是數(shù)值
- "object" —— 是對(duì)象或 null
- "function" —— 是函數(shù)
用法:
var message = " some string";
typeof message; // "string"
typeof(message); // "string"
注意:typeof 是操作符而不是函數(shù),因此圓括號(hào)可以使用,但不是必需。
4.2、undefined 類型
??undefined 類型只有一個(gè)值,即 undefined。使用 var 聲明變量但未初始化時(shí),這個(gè)變量的值就是 undefined。
??包含 undefined 值的變量與尚未定義的變量是不一樣的。例:
var message; // 變量聲明后默認(rèn)取得了 undefined 值
// 下面這個(gè)變量并沒有聲明
// var age
console.log(message); // "undefined"
console.log(age); // 產(chǎn)生錯(cuò)誤:Uncaught ReferenceError: age is not defined
??對(duì)未初始化的變量執(zhí)行 typeof 操作符會(huì)返回 undefined 值,對(duì)未聲明的變量執(zhí)行 typeof 操作符同樣會(huì)返回 undefined 值。例子:
var message; // 變量聲明后默認(rèn)取得了 undefined 值
// 下面這個(gè)變量并沒有聲明
// var age
console.log(typeof message); // "undefined"
console.log(typeof age); // "undefined"
建議:顯示地初始化變量。如果這樣做,那么當(dāng) typeof 操作符返回 "undefined" 值時(shí),就能知道被監(jiān)測的變量還沒有被聲明,而不是尚未初始化。
4.3 Null 類型
??Null 類型是第二個(gè)只有一個(gè)值的數(shù)據(jù)類型,這個(gè)特殊的值是 null 。 從邏輯角度看, null 值表示一個(gè)空對(duì)象指針。例:
var a = null;
console.log(typeof a); // "object"
建議:如果定義的變量準(zhǔn)備用于保存對(duì)象,最好將該變量初始化為 null 。這樣只要直接檢查 null 的值就可以知道相應(yīng)的變量是否已經(jīng)保存了一個(gè)對(duì)象的引用。例:
if (a != null) {// 對(duì) a 對(duì)象執(zhí)行某些操作}
??實(shí)際上, undefined 值是派生自 null 值的,因此 ECMA-262 規(guī)定對(duì)它們的相等性測試要返回 true:
console.log(null == undefined); // true
??盡管 null 和 undefined 有這樣的關(guān)系,但它們的用途完全不同。無論在什么情況下都沒有必要吧一個(gè)變量的值顯示地設(shè)置為 undefined,可是同樣的規(guī)則對(duì) null 不適用。只要意在保存對(duì)象的變量還沒有真正的保存對(duì)象,就應(yīng)該明確的讓該變量保存 null 值。這樣不僅可以體現(xiàn) null 作為空對(duì)象指針的慣例,而且也有助于進(jìn)一步區(qū)分 null 和 undefined。
4.4 Boolean 類型
??Boolean 類型是 ECMAScript 中使用最多的一種類型,該類型只有兩個(gè)字面值: true 和 false。
注意:Boolean 類型的字面值 true 和 false 是區(qū)分大小寫的。也就是說,True 和 False (以及其他的混合大小寫形式)都不是 Boolean 值,只是標(biāo)識(shí)符。
??雖然 Boolean 類型的字面值只有兩個(gè),但 ECMAScript 中所有類型的值都有與這兩個(gè) Boolean 值等價(jià)的值。可以調(diào)用轉(zhuǎn)型函數(shù) Boolean() 將一個(gè)值轉(zhuǎn)換為其對(duì)應(yīng)的 Boolean 值。
數(shù)據(jù)類型 | 轉(zhuǎn)換為 true 的值 | 轉(zhuǎn)換為 false 的值 |
---|---|---|
Boolean | true | false |
Undefined | n/a | undefined |
String | 任何非空字符串 | " " (空字符串) |
Number | 任何非零數(shù)字值(包括無窮大) | 0 和 NaN |
Object | 任何對(duì)象 | null |
n/a(或 N/A),是 not applicable 的縮寫,意思是 “不適用”。
4.5、Number 類型
數(shù)字字面量格式
- 十進(jìn)制整數(shù) — 最基本的數(shù)值字面量格式。
- 八進(jìn)制整數(shù) — 第一位必須是零(0),然后是八進(jìn)制數(shù)字序列(0~7),如果字面值中的數(shù)值超出范圍,那么前導(dǎo)零將被忽略,后面的數(shù)值將被當(dāng)作十進(jìn)制數(shù)值解析。嚴(yán)格模式下八進(jìn)制字面量無效,會(huì)導(dǎo)致支持的JavaScript引擎拋出錯(cuò)誤。
var octalNum1 = 070; // 八進(jìn)制的56
var octalNum2 = 079; // 無效的八進(jìn)制數(shù)值—解析為79
var octalNum3 = 08; // 無效的八進(jìn)制數(shù)值—解析為8
- 十六進(jìn)制整數(shù) — 前兩位必須是0x,后跟任何十六進(jìn)制數(shù)字(0 ~ 9 及 A ~ F),字母可以大寫,也可以小寫。
var hexNum1 = 0xA; // 十六進(jìn)制的 10
var hexNum2 = 0x1f; // 十六進(jìn)制的 31
在進(jìn)行算數(shù)計(jì)算時(shí),所有以八進(jìn)制和十六進(jìn)制表示的數(shù)值都將被轉(zhuǎn)換成十進(jìn)制數(shù)值。
4.5.1、 浮點(diǎn)數(shù)值
浮點(diǎn)數(shù)值 — 該數(shù)值中必須包含一個(gè)小數(shù)點(diǎn),并且小數(shù)點(diǎn)后面必須至少有一位數(shù)字。
小數(shù)點(diǎn)前面可以沒有整數(shù),但不建議這樣寫
4.5.2、 數(shù)值范圍
ECMAScript能夠表示的數(shù)值(大多數(shù)瀏覽器中):
- 最小數(shù)值保存在 Number.MIN_VALUE 中 — 5e-324。
- 最大數(shù)值保存在 Number.MAX_VALUE 中 — 1.7976931348623157e+308。
超出范圍后,這個(gè)數(shù)值被自動(dòng)轉(zhuǎn)換成 Infinity(無窮數(shù))。
確定一個(gè)數(shù)值是不是有窮的,使用 isFinite() 函數(shù),有窮返回 true
4.5.3、NaN
??NaN, 非數(shù)值(Not a Number)是一個(gè)特殊的數(shù)值,這個(gè)數(shù)值用于表示一個(gè)本來要返回?cái)?shù)值的操作數(shù)未返回?cái)?shù)值的情況(這樣就不會(huì)拋出錯(cuò)誤, 從而影響其他代碼的執(zhí)行)。
NaN 本身有兩個(gè)非同尋常的特點(diǎn):
- 任何涉及 NaN 的操作都會(huì)返回 NaN。
- NaN 與任何值都不相等,包括 NaN 本身。
- 只有 0 除以 0 才會(huì)返回NaN, 整數(shù)除以 0 返回 Infinity,負(fù)數(shù)除以 0 返回 -Infinity。
??isNaN() 函數(shù),可以判斷一個(gè)值是否“不是數(shù)值”,,任何不能被轉(zhuǎn)換為數(shù)值的值都會(huì)導(dǎo)致這個(gè)函數(shù)返回 true。
4.5.4、數(shù)值轉(zhuǎn)換
將非數(shù)值轉(zhuǎn)換成數(shù)值:
- Number() 可用于任何函數(shù)。
- parseInt()、parseFloat() 只用于將字符串轉(zhuǎn)換為數(shù)值。
Number() 函數(shù)的轉(zhuǎn)換規(guī)則:
- Boolean — true 和 false 分別被轉(zhuǎn)換為 1 和 0
- 數(shù)字值 — 只是簡單的傳入和返回
- null — 返回 0
- undefined — 返回 NaN
- 字符串 —
- 如果字符串中只包含數(shù)字 — 將其轉(zhuǎn)換成十進(jìn)制數(shù)值。
- 如果字符串中含有有效的浮點(diǎn)格式 — 將其轉(zhuǎn)換為對(duì)應(yīng)的浮點(diǎn)數(shù)值。
- 如果字符串中含有有效的十六進(jìn)制格式 — 將其轉(zhuǎn)換為相同大小的十進(jìn)制整數(shù)值。
- 如果字符串是空的 — 將其轉(zhuǎn)換為 0。
- 如果字符串包含除上述格式之外的字符 — 將其轉(zhuǎn)換為 NaN。
- 如果是對(duì)象 — 調(diào)用對(duì)象的 valueOf() 方法,然后依照前面的規(guī)則轉(zhuǎn)換返回的值;如果轉(zhuǎn)換的結(jié)果是 NaN ,則調(diào)用對(duì)象的 toString() 方法,然后在按照前面的規(guī)則轉(zhuǎn)換返回的字符串值。
var num1 = Number("Hello world!"); // NaN
var num2 = Number(" "); // 0
var num3 = Number("000011"); // 11
var num4 = Number(true); // 1
一元加操作符的操作與 Number() 函數(shù)相同
??由于 Number() 函數(shù)在轉(zhuǎn)換字符串是比較復(fù)雜而且不夠合理,因此在處理整數(shù)時(shí)更常用的是 parseInt() 函數(shù)。
??parseInt() 函數(shù)在使用時(shí)應(yīng)始終指定基數(shù)。
??parseFloat() 函數(shù)只解析十進(jìn)制數(shù)值。
4.6、String 類型
??String 類型用于表示由零或多個(gè) 16 位 Unicode 字符組成的字符序列,即字符串。字符串可以由雙引號(hào)(")或單引號(hào)(')表示,這兩種寫法都是有效的,但前后必須一致。
4.6.1、字符字面量
??String 數(shù)據(jù)類型包含一些特殊的字符字面量,也叫轉(zhuǎn)義序列,用于表示被打印字符,或者具有其他用途的字符:
字面量 | 含義 |
---|---|
\n | 換行 |
\t | 制表 |
\b | 空格 |
\r | 回車 |
\f | 進(jìn)紙 |
\ | 斜杠 |
' | 單引號(hào)(') |
" | 雙引號(hào)(") |
4.6.2、字符串的特點(diǎn)
??ECMAScript 中的字符串是不可變的,也就是說,字符串一旦創(chuàng)建,它們的值就不能改變。要改變某個(gè)變量保存的字符串,首先要銷毀原來的字符串,然后在用另一個(gè)包含新值的字符串填充該變量。這個(gè)過程是在后臺(tái)發(fā)生的,而這也是在某些舊版本的瀏覽器(如版本低于1.0的FIrefox、IE6等)中拼接字符串時(shí)速度很慢的原因所在。但在這些瀏覽器后來的版本已經(jīng)解決了這個(gè)低效率的問題。
4.6.3、轉(zhuǎn)換為字符串
兩種方法:
- toString() 方法,除 null 和 undefined 值都有這個(gè)方法。調(diào)用數(shù)值的 toString() 方法時(shí),可以傳遞一個(gè)參數(shù):輸出數(shù)值的基數(shù)。默認(rèn)情況下,toString() 方法以十進(jìn)制格式返回?cái)?shù)值的字符串表示,而通過傳遞基數(shù),toString() 可以輸出以二進(jìn)制、八進(jìn)制、十六進(jìn)制,乃至其他任意有效進(jìn)制格式表示的字符串值。
- String() 方法,將任何值轉(zhuǎn)換為字符串。null 值返回"null", undefined 返回 "undefined"。
使用:
var num = 10;
var n = null;
var boolean = true;
// toString()
num.toString(); // "10"
num.toString(2); // "1010"
boolean .toString(); // "true"
num.toString(n); // 報(bào)錯(cuò)
// String
String(num); // "10"
String(n); // "null"
String(boolean ); // "true"
將某個(gè)值轉(zhuǎn)換為字符串:num + " ";
4.7、Object類型
??ECMAScript 中的對(duì)象是一組數(shù)據(jù)和功能的集合。創(chuàng)建 Object 類型的實(shí)例并為其添加屬性和(或)方法,就可以創(chuàng)建自定義對(duì)象。
var o = new Object();
Object 的每個(gè)實(shí)例都具有下列屬性和方法:
- constructor(構(gòu)造函數(shù))—— 保存著用于創(chuàng)建當(dāng)前對(duì)象的函數(shù)。對(duì)于例子而言:構(gòu)造函數(shù)(constructor)就是 Object()。
- hasOwnProperty(propertyName)—— 用于檢查給定的屬性在當(dāng)前對(duì)象實(shí)例中(而不是在實(shí)例的原型中)是否存在。其中,作為參數(shù)的屬性名(propertyName)必須以字符串形式指定(例如:o.hasOwnProperty('name'))。
- isPrototypeOf(object)—— 用于檢查傳入的對(duì)象是否是傳入對(duì)象的原型。
- propertyIsEnumerable(propertyName)—— 用于檢查給定的屬性是否能夠使用 for-in 語句來枚舉。與hasOwnproperty() 方法一樣,作為參數(shù)的屬性名必須以字符串形式指定。
- toLocaleString() —— 返回對(duì)象的字符串表示,該字符串與執(zhí)行環(huán)境的地區(qū)對(duì)應(yīng)。
- toString() —— 返回對(duì)象的字符串表示。
- valueOf() —— 返回對(duì)象的字符串、數(shù)值或布爾值表示。通常與 toString() 方法的返回值相同。
5、 操作符
5.1、一元操作符
只能操作一個(gè)值的操作符叫做一元操作符
5.1.1、遞增和遞減操作符
var age = 0;
- 前置遞增 —— ++age; // 1
- 前置遞減 —— --age; // -1
- 后置遞增 —— age++; // 1
- 后置遞減 —— age--; // -1
遞增和遞減操作符作用于其它數(shù)據(jù)類型的值時(shí):
- 包含有效數(shù)字字符的字符串,先將其轉(zhuǎn)為數(shù)字值,再執(zhí)行加減 1 的操作,字符串變量變成數(shù)值變量。
- 不包含有效數(shù)字字符的字符串,將變量的值設(shè)置為 NaN,字符串變量變成數(shù)值變量。
- 布爾值 false,先轉(zhuǎn)換為 0 再執(zhí)行加減 1 的操作,布爾值變量變?yōu)閿?shù)值變量。
- 布爾值 true ,先轉(zhuǎn)換為 1 再執(zhí)行加減 1 的操作,布爾值變量轉(zhuǎn)為數(shù)值變量。
- 浮點(diǎn)數(shù)值,執(zhí)行加減 1 的操作。
- 對(duì)象,先調(diào)用對(duì)象的 valueOf() 方法取得一個(gè)可供操作的值,應(yīng)用上述規(guī)則。
5.1.2、一元加和減操作符
一元加操作符以一個(gè)加號(hào)(+)表示,對(duì)數(shù)值不會(huì)產(chǎn)生影響
var num = 0;
num = +num; // 仍然是 0
??對(duì)非數(shù)值應(yīng)用一元加操作符時(shí),該操作符回像 Number() 轉(zhuǎn)型函數(shù)一樣對(duì)這個(gè)值進(jìn)行轉(zhuǎn)換。
??一元減操作符用于數(shù)值時(shí),該值變?yōu)樨?fù)數(shù),用于非數(shù)值時(shí),同一元加操作符規(guī)則相同,再將得到的數(shù)值轉(zhuǎn)為負(fù)數(shù)。
var b = false; // 0
5.2、位操作符(待定)
位操作符用于在最基本的層次上,即按內(nèi)存中表示數(shù)值的位來操作數(shù)值。
5.3、布爾操作符
布爾操作符共有 3 個(gè):
- 非(NOT)
- 與(AND)
- 或(OR)
5.3.1、邏輯非
??邏輯非操作符由一個(gè)嘆號(hào)(!)表示,可以應(yīng)用與ECMAScript中的任何值。無論這個(gè)值是什么數(shù)據(jù)類型,這個(gè)操作符都會(huì)返回一個(gè)布爾值。邏輯非操作符會(huì)先將它的操作數(shù)轉(zhuǎn)換為一個(gè)布爾值,再對(duì)其求反。
邏輯非操作符遵循規(guī)則:
- 對(duì)象 —— false
- 空字符串 —— true
- 非空字符串 —— false
- 數(shù)值 0 —— true
- 非 0 數(shù)值(包括Infinity) —— false
- null —— true
- NaN —— true
- undefined —— true
同時(shí)使用兩個(gè)邏輯非操作符(!!)將一個(gè)值轉(zhuǎn)換為布爾值,同 Boolean() 函數(shù)相同。
5.3.2、邏輯與
邏輯與操作符由兩個(gè)和號(hào)(&&)表示,有兩個(gè)操作數(shù)。
邏輯與的真值表:
第一個(gè)操作數(shù) | 第二個(gè)操作數(shù) | 結(jié)果 |
---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
??邏輯與操作可以應(yīng)用于任何類型的操作數(shù)。在有一個(gè)操作數(shù)不是布爾值的情況下,邏輯與操作不一定返回布爾值,遵循規(guī)則:
- 第一個(gè)操作數(shù)是對(duì)象,返回第二個(gè)操作數(shù)
- 第二個(gè)操作數(shù)是對(duì)象,只有第一個(gè)操作數(shù)的求值結(jié)果為 true 的情況下才會(huì)返回該對(duì)象
- 兩個(gè)操作數(shù)都是對(duì)象,返回第二個(gè)操作數(shù)
- 有一個(gè)操作數(shù)是 null,返回 null
- 有一個(gè)操作數(shù)是 NaN, 返回 NaN
- 有一個(gè)操作數(shù)是 undefined, 返回 undefined
- 同時(shí)有 null、NaN 或 undefined,返回第一個(gè)對(duì)象
??邏輯與操作屬于短路操作,即如果第一個(gè)操作數(shù)能夠決定結(jié)果,就不會(huì)再對(duì)第二個(gè)操作數(shù)求值。
5.3.3、邏輯或
邏輯或操作符由兩個(gè)豎線符號(hào)(||)表示,有兩個(gè)操作數(shù)。
var result = true || false;
邏輯或的真值表:
第一個(gè)操作數(shù) | 第二個(gè)操作數(shù) | 結(jié)果 |
---|---|---|
true | true | true |
true | false | true |
false | true | true |
false | false | false |
??邏輯或操作可以應(yīng)用于任何類型的操作數(shù)。在有一個(gè)操作數(shù)不是布爾值的情況下,邏輯或操作不一定返回布爾值,遵循規(guī)則:
- 第一個(gè)操作數(shù)是對(duì)象,返回第一個(gè)操作數(shù)
- 第一個(gè)操作數(shù)的求值結(jié)果為false,返回第二個(gè)操作數(shù)
- 兩個(gè)操作數(shù)都是對(duì)象,返回第一個(gè)操作數(shù)
- 兩個(gè)操作數(shù)是 null,返回 null
- 兩個(gè)操作數(shù)是 NaN, 返回 NaN
- 兩個(gè)操作數(shù)是 undefined, 返回 undefined
- 同時(shí)有 null、NaN 或 undefined,返回第一個(gè)對(duì)象
??邏輯或操作符是短路操作,即如果第一個(gè)操作數(shù)的求值結(jié)果為 true,就不會(huì)對(duì)第二個(gè)操作數(shù)求值了。
??使用邏輯或的這一行為來避免為變量賦 null 或 undefined 值。
var obj = preferredObjcet || backupObject
5.4、乘性操作符
??ECMAScript定義了 3 個(gè)乘性操作符:乘法、除法、求模。
??在操作數(shù)為非數(shù)值的情況下會(huì)執(zhí)行自動(dòng)的類型轉(zhuǎn)換,后臺(tái)會(huì)先使用 Number() 轉(zhuǎn)型函數(shù)將其轉(zhuǎn)換為數(shù)值,也就是說,空字符串被當(dāng)作 0,布爾值 true 被當(dāng)作 1。
5.4.1、乘法
乘法操作符由一個(gè)星號(hào)(*)表示,由于計(jì)算兩個(gè)數(shù)值的乘積。
var reslult = 10 * 10;
在處理特殊值的情況下,乘法操作符遵循下列特殊的規(guī)則:
- 操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的乘法計(jì)算,如果乘積超過ECMAScript數(shù)值的表示范圍,返回 Infinity 或 -Infinity。
- 一個(gè)操作數(shù)是 NaN,結(jié)果是 NaN。
- Infinity * 0 , 結(jié)果是 NaN,。
- Infinity 與非 0 數(shù)值相乘,結(jié)果是 Infinity 或 -Infinity,取決于有符號(hào)操作數(shù)的符號(hào)。
- Infinity * Infinity, 結(jié)果是 Infinity。
- 一個(gè)操作數(shù)不是數(shù)值,在后臺(tái)調(diào)用 Number() 將其轉(zhuǎn)換為數(shù)值,再應(yīng)用上面的規(guī)則。
5.4.2、除法
除法操作符由一個(gè)斜線符號(hào)(/)表示,執(zhí)行第二個(gè)操作數(shù)除第一個(gè)操作數(shù)的計(jì)算。
var a, b;
a 除以b ,a 是被除數(shù)、b是除數(shù)(a / b)
a 除 b,b是被除數(shù)、a是除數(shù)(b / a)
除法操作符遵循下列特殊的規(guī)則:
- 操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的除法計(jì)算,如果乘積超過ECMAScript數(shù)值的表示范圍,返回 Infinity 或 -Infinity。
- 一個(gè)操作數(shù)是 NaN,結(jié)果是 NaN。
- Infinity / Infinity, 結(jié)果是 NaN。
- 0 / 0 , 結(jié)果是 NaN。
- 非 0 有限數(shù)被 0 除(非零有限數(shù) / 0),結(jié)果是 Infinity 或 -Infinity,取決于有符號(hào)操作數(shù)的符號(hào)。
- Infinity 被任何非 0 數(shù)值除( Infinity / 任何非 0 數(shù)值),結(jié)果是 Infinity 或 -Infinity,取決于有符號(hào)操作數(shù)的符號(hào)。
- 一個(gè)操作數(shù)不是數(shù)值,在后臺(tái)調(diào)用 Number() 將其轉(zhuǎn)換為數(shù)值,再應(yīng)用上面的規(guī)則。
5.4.3、求模
求模(余數(shù))操作符由一個(gè)百分號(hào)(%)表示。
var result = 26 % 5; // 等于 1
求模操作符遵循下列特殊的規(guī)則:
- 操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的除法計(jì)算,返回除得的余數(shù)。
- 無窮大值 % 有限大數(shù)值,結(jié)果是 NaN。
- 有限大的數(shù)值 % 0, 結(jié)果是 NaN 。
- Infinity % Infinity,結(jié)果是 NaN。
- 有限大的數(shù)值 % 無窮大的數(shù)值, 結(jié)果是被除數(shù)(有限大的數(shù)值)。
- 被除數(shù)是 0, 結(jié)果是 0。
- 一個(gè)操作數(shù)不是數(shù)值,在后臺(tái)調(diào)用 Number() 將其轉(zhuǎn)換為數(shù)值,再應(yīng)用上面的規(guī)則。
5.5、加性操作符
5.5.1、加法
var result = 1 + 2;
兩個(gè)操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的加法計(jì)算,然后根據(jù)下列規(guī)則返回結(jié)果:
- 一個(gè)操作數(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
一個(gè)操作符是字符串,應(yīng)用下列規(guī)則:
- 兩個(gè)都是字符串, 將第二個(gè)操作數(shù)與第一個(gè)操作數(shù)拼接起來。
- 只有一個(gè)操作數(shù)是字符串, 將另一個(gè)操作數(shù)轉(zhuǎn)換為字符串,再將兩個(gè)字符串拼接起來。
??有一個(gè)操作數(shù)是對(duì)象、數(shù)值、布爾值,調(diào)用 toString() 方法取得相應(yīng)的字符串值,在應(yīng)用前面關(guān)于字符串的規(guī)則。
??對(duì)于 undefined 和 null,分別調(diào)用 String() 函數(shù)并取得字符串 “undefined" 和 "null"。
5.5.2、減法
減法遵循規(guī)則:
- 兩個(gè)操作數(shù)都是數(shù)值,執(zhí)行常規(guī)的算數(shù)減法操作并返回結(jié)果
- 一個(gè)操作數(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
- 有一個(gè)操作數(shù)是字符串、布爾值、null、undefined,先調(diào)用 Number() 函數(shù)將其轉(zhuǎn)換為數(shù)值,再根據(jù)前面的規(guī)則執(zhí)行減法計(jì)算。如果轉(zhuǎn)換結(jié)果是 NaN,減法是結(jié)果是 NaN。
- 一個(gè)操作數(shù)是對(duì)象,掉用對(duì)象的 valueOf() 發(fā)放以取得表示該對(duì)象的數(shù)值,如果結(jié)果是 NaN,減法結(jié)果是NaN。如果對(duì)象沒有 valueOf() 方法,調(diào)用其 toString() 方法并將得到的字符串轉(zhuǎn)為數(shù)值。
5.6、關(guān)系操作符
??小于(<)、大于(>)、小于等于(<=)、大于等于(>=)這幾個(gè)關(guān)系操作符用于對(duì)兩個(gè)值進(jìn)行比較,返回一個(gè)布爾值
遵循規(guī)則:
- 兩個(gè)操作數(shù)都是數(shù)值,執(zhí)行數(shù)值比較。
- 兩個(gè)操作數(shù)都是字符串,比較兩個(gè)字符串對(duì)應(yīng)的字符編碼值。
- 一個(gè)操作數(shù)是數(shù)值,將另一個(gè)操作數(shù)轉(zhuǎn)為數(shù)值,執(zhí)行數(shù)值比較。
- 一個(gè)操作數(shù)是對(duì)象,調(diào)用對(duì)象的 valueOf() 方法,用得到的結(jié)果按前面的規(guī)則執(zhí)行比較。如果沒有 valueOf() 方法,調(diào)用 toString() 方法,按前面的規(guī)則進(jìn)行比較。
- 一個(gè)操作數(shù)是布爾值,先轉(zhuǎn)為數(shù)值,再執(zhí)行比較。
- 任何操作數(shù)與 NaN 進(jìn)行比較,結(jié)果都是 false。
5.7、相等操作符
相等和不相等 —— 先轉(zhuǎn)換再比較
全等和不全等 —— 僅比較而不轉(zhuǎn)換
5.7.1、相等和不相等
??相等操作符由像個(gè)等于號(hào)(==)表示,如果兩個(gè)操作數(shù)相等,返回 true
不相等操作符由嘆號(hào)后等等于號(hào)(!=)表示,如果兩個(gè)操作數(shù)不相等,返回 true。
這兩個(gè)操作符都會(huì)先轉(zhuǎn)換操作數(shù)(通常稱為強(qiáng)制轉(zhuǎn)型),然后再比較它們的相等性。
轉(zhuǎn)換不同的數(shù)據(jù)類型是,遵循規(guī)則:
- 一個(gè)操作數(shù)是布爾值,轉(zhuǎn)換為數(shù)值,false :0, true:1
- 一個(gè)操作數(shù)是字符串,另一個(gè)是數(shù)值,將字符串轉(zhuǎn)為數(shù)值
- 一個(gè)操作數(shù)是對(duì)象,另一個(gè)不是,調(diào)用對(duì)象的 valueOf() 方法
相等和不相等操作符在進(jìn)行比較時(shí)遵循規(guī)則:
- null 和 undefined 是相等的。
- 比較相等性之前,不能將 null 和 undefined 轉(zhuǎn)換為其他任何值
- 有一個(gè)操作數(shù)是 NaN,相等操作返回 false(提示:NaN == NaN ,返回 false)。
- 兩個(gè)操作數(shù)都是對(duì)象,比較是不是同一個(gè)對(duì)象。如果兩個(gè)操作數(shù)指向同一個(gè)對(duì)象,相等操作符返回 true。
特殊情況:
表達(dá)式 | 值 |
---|---|
null == undefined | true |
"NaN" == NaN | false |
5 == NaN | false |
NaN == NaN | false |
NaN != NaN | true |
false == 0 | true |
true == 1 | true |
true == 2 | false |
undefined == 0 | false |
null == 0 | false |
"5" == 5 | true |
5.7.2、全等和不全等
??全等操作符由 3 個(gè)等于號(hào)(===)表示,只在兩個(gè)操作數(shù)未經(jīng)轉(zhuǎn)換就相等的情況下返回 true。
var result1 = ("55" == 55); // true, 因?yàn)檗D(zhuǎn)換后相等
var result2 = ("55" === 55); // false, 因?yàn)椴煌臄?shù)據(jù)類型不相等
不全等操作符由一個(gè)嘆號(hào)后跟兩個(gè)等于號(hào)(!==)表示。
提示: null == undefined; // true
null === unefined; // false, 類型不同
由于相等和不相等操作符存在類型轉(zhuǎn)換問題,而為了保持代碼中數(shù)據(jù)類型的完整性,推薦使用全等和不全等操作。
1.5.8、條件操作符
variable = boolean_expression ? true_value : false_value;
5.9、賦值操作符
??簡單的賦值操作符由等于號(hào)(=)表示,其作用就是把右側(cè)的值賦給左側(cè)的變量。
??在等于號(hào)(=)前面添加乘性操作符、加性操作符或位操作符,就可以完成復(fù)合賦值操作。復(fù)合賦值操作相當(dāng)于常規(guī)表達(dá)式的簡寫形式。
var num = 10;
num = num + 10; => num += 10;
復(fù)合賦值操作符:
- 乘/賦值 (*=)
- 除/賦值 (/=)
- 模/賦值 (%=)
- 加/賦值 (+=)
- 減/賦值 (-=)
- 左移/賦值 (<<=)
- 有符號(hào)右移/賦值(>>=)
- 無符號(hào)右移/賦值 (>>>=)
復(fù)合賦值操作符的主要目的是簡化賦值操作,使用它們不會(huì)帶來任何性能的提升。
5.10、逗號(hào)操作符
使用逗號(hào)操作符可以在一條語句中執(zhí)行多個(gè)操作。
var num1 = 1, num2 = 2, num3 = 3;
??逗號(hào)操作符多用于聲明多個(gè)變量。也可以用于賦值,用于賦值時(shí),逗號(hào)操作符總會(huì)返回表達(dá)式中的最后一項(xiàng)。
var num = (1, 2, 3, 4, 5); // num 值為 5
6、語句
6.1、if 語句
if (condition) {
statement1
} else {
statement2
}
6.2、do-while 語句
??do-while 語句是一種后測試循環(huán)語句,即只有在循環(huán)體中的代碼塊執(zhí)行之后,才會(huì)測試出口條件。換句話說,在對(duì)條件表達(dá)式求值之前,循環(huán)體內(nèi)的代碼至少會(huì)被執(zhí)行一次。
語法:
do {
statement
} while (expression);
expression 為 true時(shí),繼續(xù)循環(huán),為 false時(shí),跳出循環(huán)。
6.3、 while 語句
??while 語句屬于前測試循環(huán)語句,也就是說,在循環(huán)體內(nèi)的代碼被執(zhí)行之前,就會(huì)對(duì)出口條件求值,因此,循環(huán)體內(nèi)的代碼有可能永遠(yuǎn)不會(huì)被執(zhí)行。
語法:
while (expression) {
statement
}
6.4、for 語句
??for 語句也是前測試循環(huán)語句,但它具有在執(zhí)行循環(huán)之前初始化變量和定義循環(huán)后要執(zhí)行的代碼的能力。
語法:
for (initialization; expression; post-loop-expression) {
statement
}
??for 語句中的變量的初始化可以在循環(huán)外部執(zhí)行。
??for 語句中的初始化表達(dá)式、控制表達(dá)式和循環(huán)后表達(dá)式都是可選的,將這三個(gè)表達(dá)式全部省略,就會(huì)創(chuàng)建一個(gè)無限循環(huán)。
6.5、for-in 語句
for-in 語句是一種精準(zhǔn)的迭代語句,可以用來枚舉對(duì)象的屬性。
語法:
for (property in expression) {
statement
}
6.6、 label 語句
使用 label 語句可以在代碼中添加標(biāo)簽。
語法:
label: statement
示例:
start: for (var i = 0; i < 10; i++) {
console.log(i);
}
??定義的 start 標(biāo)簽可以在將來由 break 或 continue 語句引用。加標(biāo)簽的語句一般都要與 for 語句等循環(huán)語句配合使用。
6.7、break 和 continue 語句
break 和continue 語句用于在循環(huán)中精確地控制代碼的執(zhí)行。
break 語句會(huì)立即退出循環(huán),強(qiáng)制繼續(xù)執(zhí)行循環(huán)后面的語句。
continue 語句會(huì)立即退出循環(huán),從循環(huán)的頂部繼續(xù)執(zhí)行。
// break 語句
var num = 0;
for (var i = 1; i < 10; i++) {
if (i % 5 == 0) {
break;
}
num++;
}
console.log(num); // 4
// continue 語句
var num = 0;
for (var i = 1; i < 10; i++) {
if (i % 5 == 0) {
continue ;
}
num++;
}
console.log(num); // 8
不論是 break 語句還是 continue 語句,都會(huì)立即退出當(dāng)前循環(huán),所以 i = 5 后的 num++ 都不再執(zhí)行。
??break 和 continue 語句都可以和 label 語句聯(lián)合使用,從而返回代碼中特定的位置。這種聯(lián)合使用的情況多發(fā)生在循環(huán)嵌套的情況下。
示例:
var num = 0;
outermost:
for (var i = 0; i < 10; i++) {
for (lei j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
break outermost; // num 55
// continue outermost; // num 95
}
num++;
}
}
console.log(num);
建議:使用 label 語句,一定要使用描述性的標(biāo)簽,同時(shí)不要嵌套過多的循環(huán)。
6.8、with 語句
with 語句的作用是將代碼的作用域設(shè)置到一個(gè)特定的對(duì)象中。
語法:
with (expression) {
statement
}
定義 with 語句的目的主要是為了簡化多次編寫同一個(gè)對(duì)象的工作
示例:
var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;
with (location) {
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}
??嚴(yán)格模式下不允許使用 with 語句,否則將視為語法錯(cuò)誤。
??由于大量使用 with 語句會(huì)導(dǎo)致性能下降,同時(shí)也會(huì)給調(diào)試代碼造成困難,因此在開發(fā)大型應(yīng)用程序是,不建議使用 with 語句。
6.9、switch 語句
switch 語句與 if 語句的關(guān)系最為密切,是一種流控制語句。
switch (expression) {
case value: statement
break;
case value: statement
break;
case value: statement
break;
default: statement
}
??switch 語句中的每一種情形(case)的含義是:“如果表達(dá)式等于這個(gè)值(value),則執(zhí)行后面的語句(statement)”。
??break 關(guān)鍵字會(huì)導(dǎo)致代碼執(zhí)行流跳出 switch 語句,如果省略break關(guān)鍵字,就會(huì)導(dǎo)致執(zhí)行完當(dāng)前 case 后,繼續(xù)執(zhí)行下一個(gè) case。
??最后的 default 關(guān)鍵字則用于在表達(dá)式不匹配前面任何一種情形的時(shí)候,執(zhí)行機(jī)動(dòng)代碼(因此,也相當(dāng)于一個(gè) else 語句)。
合并多種情形:
switch (i) {
case 25:
case 35:
console.log("25 or 35");
break;
case 45:
console.log("45");
break;
default:
console.log("other");
}
switch 語句在比較值時(shí)使用的是全等操作符,因此不會(huì)發(fā)生類型轉(zhuǎn)換。
7、函數(shù)
??通過函數(shù)可以封裝任意多條語句,并可以在任何地方、任何時(shí)候調(diào)用執(zhí)行。ECMAScript 中的函數(shù)使用 function 關(guān)鍵字來聲明,后跟一組參數(shù)以及函數(shù)體。
語法:
// 聲明函數(shù)
function functionName (arg0, arg1, ..., argN) {
statements
}
functionName (); // 調(diào)用函數(shù)
function sum (num1, num2) {
return num1 + num2; // 通過 return 后跟要返回的值來實(shí)現(xiàn)返回值
}
??這個(gè)函數(shù)會(huì)在執(zhí)行完 return 語句后立即停止并退出。因此,位于 return 語句之后的任何代碼都永遠(yuǎn)不會(huì)執(zhí)行。
??return 語句也可以不帶任何返回值。這種情況下,函數(shù)在停止執(zhí)行后將返回 undefined 值。這種用法一般在需要提前停止函數(shù)執(zhí)行而又不需要返回值的情況下。
嚴(yán)格模式對(duì)函數(shù)有一些限制:
- 不能把函數(shù)命名為 eval 或 arguments。
- 不能把參數(shù)命名為 eval 或 arguments。
- 不能出現(xiàn)兩個(gè)命名參數(shù)同名的情況。
如果發(fā)生以上情況,就會(huì)導(dǎo)致語法錯(cuò)誤,代碼無法執(zhí)行。
7.1、理解參數(shù)
??ECMAScript 函數(shù)不介意傳遞進(jìn)來多少個(gè)參數(shù),也不在乎傳進(jìn)來的參數(shù)是什么數(shù)據(jù)類型。也就是說,即使你定義的函數(shù)只接受兩個(gè)參數(shù),在調(diào)用這個(gè)函數(shù)時(shí)也未必一定要傳遞兩個(gè)參數(shù)。可以傳遞一個(gè)、三個(gè)甚至不傳參數(shù)。
??原因:ECMAScript 中的參數(shù)在內(nèi)部是用一個(gè)數(shù)組來表示的,函數(shù)接收到的始終都是這個(gè)數(shù)組,而不關(guān)心數(shù)組中包含哪些參數(shù)。
??在函數(shù)體內(nèi)部可以通過 arguments 對(duì)象來訪問這個(gè)參數(shù)數(shù)組,從而獲取傳遞給函數(shù)的每一個(gè)參數(shù)。
??其實(shí),arguments 對(duì)象只是與數(shù)組類似(并不是 Array 的實(shí)例),因?yàn)榭梢允褂梅嚼ㄌ?hào)語法訪問它的每一個(gè)元素(第一個(gè)元素是 arguments[0]),使用 length 屬性來確定傳遞進(jìn)來多少個(gè)參數(shù)。
function sayHi (name, message) {
console.log("hello " + name + "," + message);
}
function sayHi () {
console.log("hello " + arguments[0] + "," + arguments[1]);
}
// ECMAScript 函數(shù)中命名的參數(shù)只是提供便利,不是必需的
??通過訪問 arguments 對(duì)象的 length 屬性可以獲知有多少個(gè)參數(shù)傳遞給了函數(shù)。可以利用這個(gè)特點(diǎn)來實(shí)現(xiàn)不同的功能。
function doAdd () {
if (arguments.length === 1) {
console.log(arguments[0] + 10);
} else if (arguments.length === 2) {
console.log(arguments[0] + arguments[1]);
}
}
arguments 對(duì)象可以與命名參數(shù)一起使用。
function doAdd (num1, num2) {
if (arguments.length === 1) {
console.log(num1 + 10);
} else if (arguments.length === 2) {
console.log(arguments[0] + num2);
}
}
在非嚴(yán)格模式下:
arguments 的值永遠(yuǎn)與對(duì)應(yīng)命名參數(shù)的值保持同步。
function doAdd (num1, num2) {
arguments[1] = 10;
console.log(num2);
}
doAdd(1); // undefined
doAdd(1, 2); // 10
??這并不是說讀取這兩個(gè)值回訪問相同的內(nèi)存空間,num2 和 arguments[1] 的內(nèi)存空間是獨(dú)立的,但它們的值會(huì)同步。
??但如果只傳入一個(gè)參數(shù),那么為了 arguments[1] 設(shè)置的不會(huì)反應(yīng)到命名參數(shù)中。這是因?yàn)?arguments 對(duì)象的長度是由傳入的參數(shù)個(gè)數(shù)決定的,不是由定義函數(shù)時(shí)命名參數(shù)的個(gè)數(shù)決定的。
??沒有傳遞值的命名參數(shù)自動(dòng)被賦予 undefined 值,就像定義變量沒有初始化一樣。
??嚴(yán)格模式上述賦值無效, 修改 arguments[1] 的值不會(huì)影響 num2 的值。
ECMAscript 中的所有參數(shù)傳遞都是值,不能通過引用傳遞參數(shù)。
7.2、沒有重載
??ECMAScript 中定義同名函數(shù),后定義的覆蓋先定義的函數(shù),調(diào)用函數(shù)時(shí)僅執(zhí)行后面的方法。
重載函數(shù):在相同的聲明域中的函數(shù)名相同的,而參數(shù)表不同的,即通過函數(shù)的參數(shù)表而唯一標(biāo)識(shí)并且來區(qū)分函數(shù)的一種特殊的函數(shù)。
小結(jié)
??JavaScript 的核心語言特性在 ECMA-262 中是以名為 ECMAscript 的偽語言的形式定義的。
??ECMAscript 中包含了所有基本的語法、操作符、數(shù)據(jù)類型以及完成基本的計(jì)算任務(wù)所必須的對(duì)象,但沒有對(duì)取得輸入和產(chǎn)生輸出的機(jī)制作出規(guī)定。
ECMAscript 中的基本要素:
- ECMAscript 中的基本數(shù)據(jù)類型包括 Undefined、Null、Boolean、Number 和 String。
- ECMAscript 沒有為整數(shù)和浮點(diǎn)數(shù)值分別定義不同的數(shù)據(jù)類型,Number 類型可用于表示所有數(shù)值。
- ECMAscript 中也有一種復(fù)雜的數(shù)據(jù)類型,即 Object 類型,該類型是這門語言中所有對(duì)象的基礎(chǔ)類型。
- 嚴(yán)格模式為這門語言中容易出錯(cuò)的地方施加了限制。
- ECMAscript 中的基本操作符:算數(shù)操作符、布爾操作符、關(guān)系操作符、相等操作符、賦值操作符。
- ECMAscript 中的流控制語句: if 語句、for 語句、switch 語句等。
- 無需指定函數(shù)的返回值,因?yàn)槿魏?ECMAscript 函數(shù)都可以在任何時(shí)候返回任何值。
- 未指定返回值的函數(shù)返回的是一個(gè)特殊的 undefined 值。
- ECMAscript 中沒有函數(shù)簽名的概念,其函數(shù)參數(shù)是以一個(gè)包含零或多個(gè)值的數(shù)組的形式傳遞的。
- 可以向 ECMAScript 函數(shù)傳遞任意數(shù)量的參數(shù),并且可以通過 arguments 對(duì)象訪問這些參數(shù)。
- 由于不存在函數(shù)簽名的特性,ECMAScript 函數(shù)不能重載。