JavaScript 語言的每一個(gè)值,都屬于某一種數(shù)據(jù)類型。JavaScript 的數(shù)據(jù)類型,共有六種。
- 數(shù)值(number):整數(shù)和小數(shù)(比如
1和3.14) - 字符串(string):文本(比如
Hello World)。 - 布爾值(boolean):表示真?zhèn)蔚膬蓚€(gè)特殊值,即
true(真)和false(假) -
undefined:表示“未定義”或不存在,即由于目前沒有定義,所以此處暫時(shí)沒有任何值 -
null:表示空值,即此處的值為空。 - 對(duì)象(object):各種值組成的集合。
通常,數(shù)值、字符串、布爾值這三種類型,合稱為原始類型(primitive type)的值,即它們是最基本的數(shù)據(jù)類型,不能再細(xì)分了。對(duì)象則稱為合成類型(complex type)的值,因?yàn)橐粋€(gè)對(duì)象往往是多個(gè)原始類型的值的合成,可以看作是一個(gè)存放各種值的容器。至于undefined和null,一般將它們看成兩個(gè)特殊值。
對(duì)象可以分成三類:
- 狹義的對(duì)象(object)
- 數(shù)組(array)
- 函數(shù)(function)
關(guān)于typeof運(yùn)算符
typeof運(yùn)算符可以返回一個(gè)值的數(shù)據(jù)類型。
數(shù)值、字符串、布爾值分別返回number、string、boolean。
typeof 123 // "number"
typeof '123' // "string"
typeof false // "boolean"
函數(shù)返回function。(函數(shù)屬于對(duì)象的一種,理論應(yīng)該返回object,但是js里是返回function,算是bug)
undefined返回undefined。
利用這一點(diǎn),typeof可以用來檢查一個(gè)沒有聲明的變量,而不報(bào)錯(cuò)。
a
// ReferenceError: v is not defined
typeof a
// "undefined"
上面代碼中,變量a沒有用var命令聲明,直接使用就會(huì)報(bào)錯(cuò)。但是,放在typeof后面,就不報(bào)錯(cuò)了,而是返回undefined。
對(duì)象返回object。
typeof window // "object"
typeof {} // "object"
typeof [] // "object"
null返回object。(實(shí)際上null的類型就是null,返回object也算是bug)
typeof null // "object"
null返回的類型是object,這是由于歷史原因造成的。1995年的 JavaScript 語言第一版,只設(shè)計(jì)了五種數(shù)據(jù)類型(對(duì)象、整數(shù)、浮點(diǎn)數(shù)、字符串和布爾值),沒考慮null,只把它當(dāng)作object的一種特殊值。后來null獨(dú)立出來,作為一種單獨(dú)的數(shù)據(jù)類型,為了兼容以前的代碼,typeof null返回object就沒法改變了。
一、數(shù)值(number)
- 關(guān)于數(shù)值的進(jìn)制
使用字面量(literal)直接表示一個(gè)數(shù)值時(shí),JavaScript 對(duì)整數(shù)提供四種進(jìn)制的表示方法:十進(jìn)制、十六進(jìn)制、八進(jìn)制、二進(jìn)制。
- 十進(jìn)制:沒有前導(dǎo)0的數(shù)值。
- 八進(jìn)制:有前綴
0o或0O的數(shù)值,或者有前導(dǎo)0、且只用到0-7的八個(gè)阿拉伯?dāng)?shù)字的數(shù)值。 - 十六進(jìn)制:有前綴
0x或0X的數(shù)值。 - 二進(jìn)制:有前綴
0b或0B的數(shù)值。
默認(rèn)情況下,JavaScript 內(nèi)部會(huì)自動(dòng)將八進(jìn)制、十六進(jìn)制、二進(jìn)制轉(zhuǎn)為十進(jìn)制。
如果八進(jìn)制、十六進(jìn)制、二進(jìn)制的數(shù)值里面,出現(xiàn)不屬于該進(jìn)制的數(shù)字,就會(huì)報(bào)錯(cuò)。
- 關(guān)于NaN
NaN是 JavaScript 的特殊值,表示“非數(shù)字”(Not a Number),主要出現(xiàn)在將字符串解析成數(shù)字出錯(cuò)的場合。
2 - 'w' //報(bào)錯(cuò)
上面代碼運(yùn)行時(shí),會(huì)自動(dòng)將字符串x轉(zhuǎn)為數(shù)值,但是由于x不是數(shù)值,所以最后得到結(jié)果為NaN,表示它是“非數(shù)字”(NaN)。
NaN不是獨(dú)立的數(shù)據(jù)類型,而是一個(gè)特殊數(shù)值,它的數(shù)據(jù)類型依然屬于Number。
NaN不等于任何值,包括它本身。
NaN === NaN // false
二、字符串(string)
- 定義
字符串就是零個(gè)或多個(gè)排在一起的字符,放在單引號(hào)或雙引號(hào)之中。
'bbb'
"aaa"
單引號(hào)字符串的內(nèi)部,可以使用雙引號(hào)。雙引號(hào)字符串的內(nèi)部,可以使用單引號(hào)。
"'key' = value"
'hello "world" yeah'
如果要在單引號(hào)字符串的內(nèi)部,使用單引號(hào),就必須在內(nèi)部的單引號(hào)前面加上反斜杠,用來轉(zhuǎn)義。雙引號(hào)字符串內(nèi)部使用雙引號(hào),也是如此。
'go go \'go\'' //"go go 'go'"
注意,轉(zhuǎn)義符\與后面的任何字符數(shù)字都只算一個(gè)length,轉(zhuǎn)義符也可以轉(zhuǎn)轉(zhuǎn)義本身。\\
空字符串''和空格字符串' '是不一樣的,前者length為0,后者為1。
如果長字符串必須分成多行,可以在每一行的尾部使用反斜杠。(不建議這種方法)
var a ='a\
c\
e';
輸出的時(shí)候還是單行,效果與寫在同一行完全一樣。注意,反斜杠的后面必須是換行符,而不能有其他字符(比如空格),否則會(huì)報(bào)錯(cuò)。
連接運(yùn)算符(+)可以連接多個(gè)單行字符串,將長字符串拆成多行書寫,輸出的時(shí)候也是單行。(分成多行建議這種方法)
var b ='a'
+'c'
+'f';
三、布爾值(Boolean)
布爾值代表“真”和“假”兩個(gè)狀態(tài)?!罢妗庇藐P(guān)鍵字true表示,“假”用關(guān)鍵字false表示。布爾值只有這兩個(gè)值。
相與運(yùn)算符&&
a&&b必須要a和b同時(shí)為true或者false,結(jié)果才會(huì)是true false;
或運(yùn)算符|| 只要a或者b有一個(gè)是true時(shí),結(jié)果就是true,只有當(dāng)ab同時(shí)為false時(shí),結(jié)果才是false。
四、null 和 undefined
null與undefined都可以表示“沒有”,含義非常相似。將一個(gè)變量賦值為undefined或null,都表示什么都沒有。
區(qū)別:
- 變量沒有被賦值 ——>undefined 聲明了但是沒有定義的變量
- var obj = null ——>null 空對(duì)象
五、對(duì)象(object)
- 生成方法
對(duì)象(object)是 JavaScript 語言的核心概念,也是最重要的數(shù)據(jù)類型。對(duì)象就是一組“鍵值對(duì)”(key-value)的集合,是一種無序的復(fù)合數(shù)據(jù)集合。
var obj = {
foo: 'Hello',
bar: 'World'
};
上面代碼中,大括號(hào)就定義了一個(gè)對(duì)象,它被賦值給變量obj,所以變量obj就指向一個(gè)對(duì)象。該對(duì)象內(nèi)部包含兩個(gè)鍵值對(duì)(又稱為兩個(gè)“成員”),第一個(gè)鍵值對(duì)是foo: 'Hello',其中foo是“鍵名”(成員的名稱),字符串Hello是“鍵值”(成員的值)。鍵名與鍵值之間用冒號(hào)分隔。第二個(gè)鍵值對(duì)是bar: 'World',bar是鍵名,World是鍵值。兩個(gè)鍵值對(duì)之間用逗號(hào)分隔。
鍵名
對(duì)象的所有鍵名都是字符串,所以加不加引號(hào)都可以。如果鍵名是數(shù)值,會(huì)被自動(dòng)轉(zhuǎn)為字符串。
如果鍵名不符合標(biāo)識(shí)名的條件(比如第一個(gè)字符為數(shù)字,或者含有空格或運(yùn)算符),且也不是數(shù)字,則必須加上引號(hào),否則會(huì)報(bào)錯(cuò)。
對(duì)象的每一個(gè)鍵名又稱為“屬性”(property),它的“鍵值”可以是任何數(shù)據(jù)類型。如果一個(gè)屬性的值為函數(shù),通常把這個(gè)屬性稱為“方法”,它可以像函數(shù)那樣調(diào)用。屬性的讀取
讀取對(duì)象的屬性,有兩種方法,一種是使用點(diǎn)運(yùn)算符,還有一種是使用方括號(hào)運(yùn)算符。
var obj = {
p: 'Hello'
};
obj.p // "Hello"
obj['p'] // "Hello"
上面代碼分別采用點(diǎn)運(yùn)算符和方括號(hào)運(yùn)算符,讀取屬性p。
注意,如果使用方括號(hào)運(yùn)算符,鍵名必須放在引號(hào)里面,否則會(huì)被當(dāng)作變量處理。
var f = 'b';
var obj = {
f: 1,
b: 2
};
obj.f // 1
obj[f] // 2
上面代碼中,引用對(duì)象obj的f屬性時(shí),如果使用點(diǎn)運(yùn)算符,f就是字符串;如果使用方括號(hào)運(yùn)算符,但是不使用引號(hào),那么f就是一個(gè)變量,指向字符串b。
方括號(hào)運(yùn)算符內(nèi)部還可以使用表達(dá)式。數(shù)字鍵可以不加引號(hào),因?yàn)闀?huì)自動(dòng)轉(zhuǎn)成字符串。
obj['hello' + ' world']
obj[3 + 3]
注意,數(shù)值鍵名不能使用點(diǎn)運(yùn)算符(因?yàn)闀?huì)被當(dāng)成小數(shù)點(diǎn)),只能使用方括號(hào)運(yùn)算符。
var obj = {
123: 'hello world'
};
obj.123 // 報(bào)錯(cuò)
obj[123] // "hello world"
上面代碼的第一個(gè)表達(dá)式,對(duì)數(shù)值鍵名123使用點(diǎn)運(yùn)算符,結(jié)果報(bào)錯(cuò)。第二個(gè)表達(dá)式使用方括號(hào)運(yùn)算符,結(jié)果就是正確的。
- 屬性的查看
查看一個(gè)對(duì)象本身的所有屬性,可以使用Object.keys方法。
var obj = {
key1: 1,
key2: 2
};
Object.keys(obj);
// ['key1', 'key2']
- 屬性的刪除:delete 命令
delete命令用于刪除對(duì)象的屬性,刪除成功后返回true。
var obj = { p: 1 };
Object.keys(obj) // ["p"]
delete obj.p // true
obj.p // undefined
Object.keys(obj) // []
上面代碼中,delete命令刪除對(duì)象obj的p屬性。刪除后,再讀取p屬性就會(huì)返回undefined,而且Object.keys方法的返回值也不再包括該屬性。
注意,刪除一個(gè)不存在的屬性,delete不報(bào)錯(cuò),而且返回true。因此,不能根據(jù)delete命令的結(jié)果,認(rèn)定某個(gè)屬性是存在的。
只有一種情況,delete命令會(huì)返回false,那就是該屬性存在,且不得刪除。
- 屬性是否存在:in 運(yùn)算符
in運(yùn)算符用于檢查對(duì)象是否包含某個(gè)屬性(注意,檢查的是鍵名,不是鍵值),如果包含就返回true,否則返回false。
var obj = { a: 1 };
'a' in obj // true
- 屬性的遍歷:for...in 循環(huán)
for...in循環(huán)用來遍歷一個(gè)對(duì)象的全部屬性。
var obj = {a: 1, b: 2};
for (var key in obj) {
console.log(key);
console.log(obj[key]);
}
// a
// 1
// b
// 2
注意,遍歷出的順序并不一定是按照對(duì)象內(nèi)部的順序排列的。它遍歷的是對(duì)象所有可遍歷(enumerable)的屬性,會(huì)跳過不可遍歷的屬性。