一陕悬、初識(shí)數(shù)據(jù)類型
1. 概要
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):各種值組成的集合艾蓝;
Symbol類型 :不介紹。
對(duì)象是最復(fù)雜的數(shù)據(jù)類型斗塘,又可以分成三個(gè)子類型赢织。
狹義的對(duì)象(object)
數(shù)組(array)
函數(shù)(function)
2. typeof 運(yùn)算符
由于ECMAScript是松散型,JavaScript 有三種方法馍盟,可以確定一個(gè)值到底是什么類型于置。
typeof運(yùn)算符;
instanceof運(yùn)算符贞岭;
Object.prototype.toString方法八毯。
用typeof檢測變量可能返回以下某個(gè)字符串。
null開始為Object類型的一個(gè)數(shù)據(jù)瞄桨,后來獨(dú)立為一種數(shù)據(jù)類型话速,為了兼容以前的代碼,typeof null返回object就沒法改變了讲婚。
二尿孔、數(shù)據(jù)類型詳解
1. null 和 undefined
1.1 概述
null表示‘空值’,undefined表示‘未定義’筹麸。
1.2 用法和含義
null表示‘空值’活合,調(diào)用函數(shù)時(shí),某個(gè)參數(shù)未設(shè)置任何值物赶,這時(shí)就可以傳入null白指,表示該參數(shù)為空。比如酵紫,某個(gè)函數(shù)接受引擎拋出的錯(cuò)誤作為參數(shù)告嘲,如果運(yùn)行過程中未出錯(cuò),那么這個(gè)參數(shù)就會(huì)傳入null奖地,表示未發(fā)生錯(cuò)誤橄唬。
undefined表示“未定義”,下面是返回undefined的典型場景参歹。
// 變量聲明了仰楚,但沒有賦值
var i;
i // undefined
// 調(diào)用函數(shù)時(shí),應(yīng)該提供的參數(shù)沒有提供,該參數(shù)等于 undefined
function f(x) {
return x;
}
f() // undefined
// 對(duì)象沒有賦值的屬性
var o = new Object();
o.p // undefined
// 函數(shù)沒有返回值時(shí)僧界,默認(rèn)返回 undefined
function f() {}
f() // undefined
2. 布爾值
布爾值代表“真”和“假”兩個(gè)狀態(tài)侨嘀。“真”用關(guān)鍵字true表示捂襟,“假”用關(guān)鍵字false表示咬腕。
3. 數(shù)值
3.1 概述
i. 浮點(diǎn)數(shù)
JavaScript 語言的底層沒有整數(shù),所有數(shù)字都是以64位浮點(diǎn)數(shù)形式儲(chǔ)存葬荷;所以涨共,1與1.0是同一個(gè)數(shù);某些運(yùn)算只有整數(shù)才能完成闯狱,此時(shí) JavaScript 會(huì)自動(dòng)把64位浮點(diǎn)數(shù)煞赢,轉(zhuǎn)成32位整數(shù),然后再進(jìn)行運(yùn)算哄孤。
由于浮點(diǎn)數(shù)不是精確的值照筑,所以涉及小數(shù)的比較和運(yùn)算要特別小心。
0.1 + 0.2 === 0.3
// false
0.3 / 0.1
// 2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1)
// false
ii. 數(shù)值精度
根據(jù)國際標(biāo)準(zhǔn) IEEE 754瘦陈,JavaScript 浮點(diǎn)數(shù)的64個(gè)二進(jìn)制位凝危,從最左邊開始,是這樣組成的晨逝。
第1位:符號(hào)位蛾默,0表示正數(shù),1表示負(fù)數(shù)捉貌;
第2位到第12位(共11位):指數(shù)部分支鸡;
第13位到第64位(共52位):小數(shù)部分(即有效數(shù)字)。
簡單的法則就是趁窃,JavaScript 對(duì)15位的十進(jìn)制數(shù)都可以精確處理牧挣。
iii. 數(shù)值范圍
JavaScript 能夠表示的數(shù)值范圍為(21024,2-1023)醒陆,超出這個(gè)范圍的數(shù)無法表示瀑构。
如果一個(gè)數(shù)大于等于2的1024次方,那么就會(huì)發(fā)生“正向溢出”刨摩,即 JavaScript 無法表示這么大的數(shù)寺晌,這時(shí)就會(huì)返回Infinity。
如果一個(gè)數(shù)小于等于2的-1075次方(指數(shù)部分最小值-1023澡刹,再加上小數(shù)部分的52位)呻征,那么就會(huì)發(fā)生為“負(fù)向溢出”,即 JavaScript 無法表示這么小的數(shù)罢浇,這時(shí)會(huì)直接返回0陆赋。
var x = 0.5;
for(var i = 0; i < 25; i++) {
x = x * x;
}
x // 0
3.2 普通數(shù)值
i. 普通數(shù)值的表示法有進(jìn)制表示和科學(xué)計(jì)數(shù)
- 科學(xué)計(jì)數(shù)法允許字母e或E的后面边篮,跟著一個(gè)整數(shù),表示這個(gè)數(shù)值的指數(shù)部分奏甫。
- 進(jìn)制表示有二進(jìn)制、八進(jìn)制凌受、十進(jìn)制阵子、十六進(jìn)制數(shù)值,前綴分別0B胜蛉、0O挠进、無前綴、0X,例如:0B10000誊册、0O20领突、16、0X10為分別使用二案怯、八君旦、十、十六進(jìn)制表示同一數(shù)值嘲碱。
ii. 普通數(shù)值的自動(dòng)轉(zhuǎn)換
JavaScript 會(huì)自動(dòng)將數(shù)值轉(zhuǎn)為科學(xué)計(jì)數(shù)法表示金砍。
- 小數(shù)點(diǎn)后的零多于5個(gè);
- 小數(shù)點(diǎn)前的數(shù)字多于21位麦锯。
JavaScript 內(nèi)部會(huì)自動(dòng)將八進(jìn)制恕稠、十六進(jìn)制、二進(jìn)制轉(zhuǎn)為十進(jìn)制扶欣,數(shù)字或字母不匹配進(jìn)制將會(huì)報(bào)錯(cuò)鹅巍。
ES5普通模式,在有前導(dǎo)0的數(shù)值會(huì)被視為八進(jìn)制料祠,但是如果前導(dǎo)0后面有數(shù)字8和9骆捧,則該數(shù)值被視為十進(jìn)制。
3.3 特殊數(shù)值
i.正零和負(fù)零
正零和負(fù)零都會(huì)被當(dāng)作正常的0术陶,唯一有區(qū)別的場合是當(dāng)+0或-0作為分母凑懂,如1 / +0,1 / -0梧宫,0 / 0 返回的值接谨,分別得到+Infinity,-Infinity塘匣,NaN脓豪。
ii. NaN
- 含義:NaN是數(shù)據(jù)類型屬于Number的非數(shù)值;
- 運(yùn)算規(guī)則:NaN不等于任何值忌卤,包括它本身扫夜,NaN與任何數(shù)(包括它自己)的運(yùn)算,得到的都是NaN。
iii. Infinity
由于數(shù)值正向溢出(overflow)笤闯、負(fù)向溢出(underflow)和被0除堕阔,JavaScript都不報(bào)錯(cuò),而是返回Infinity颗味,所以單純的數(shù)學(xué)運(yùn)算幾乎沒有可能拋出錯(cuò)誤超陆。
Infinity + Infinity // Infinity
Infinity * Infinity // Infinity
Infinity - Infinity // NaN
Infinity / Infinity // NaN
0 * Infinity // NaN
0 / Infinity // 0
Infinity / 0 // Infinity
null * Infinity // NaN
null / Infinity // 0
Infinity / null // Infinity
undefined + Infinity // NaN
undefined - Infinity // NaN
undefined * Infinity // NaN
undefined / Infinity // NaN
Infinity / undefined // NaN
Infinity大于一切數(shù)值(除了NaN),-Infinity小于一切數(shù)值(除了NaN),Infinity與NaN比較浦马,總是返回false时呀。
3.4 特殊數(shù)值判斷方法
i. isNaN()
isNaN方法可以用來判斷一個(gè)值是否為NaN,只對(duì)數(shù)值有效晶默,如果傳入其他值谨娜,會(huì)被Number函數(shù)先轉(zhuǎn)成數(shù)值。
ii. isFinite()
除了Infinity磺陡、-Infinity趴梢、NaN和undefined這幾個(gè)值會(huì)返回false,isFinite對(duì)于其他的數(shù)值都會(huì)返回true币他。
4. 字符串
4.1 概述
字符串就是零個(gè)或多個(gè)排在一起的字符垢油,放在單引號(hào)或雙引號(hào)之中,默認(rèn)只能寫在一行內(nèi)圆丹,ES6中可使用反引號(hào)(``)替代單雙引號(hào)滩愁,讓字符串寫在多行。
JavaScript 的單位字符長度固定為16位長度辫封,只能以2個(gè)字節(jié)的UTF-16格式儲(chǔ)存硝枉,所以處理的時(shí)候,JavaScript 返回的字符串長度可能是不正確的倦微。
4.2 轉(zhuǎn)義
需要用反斜杠轉(zhuǎn)義的特殊字符妻味,主要有下面這些,若前面加反斜杠沒有特殊含義欣福,反斜杠會(huì)被自動(dòng)省略责球。
- \0 :null(\u0000)
- \b :后退鍵(\u0008)
- \f :換頁符(\u000C)
- \n :換行符(\u000A)
- \r :回車鍵(\u000D)
- \t :制表符(\u0009)
- \v :垂直制表符(\u000B)
- \' :單引號(hào)(\u0027)
- \" :雙引號(hào)(\u0022)
- \\ :反斜杠(\u005C)
- \HHH (三個(gè)八進(jìn)制數(shù))
- \xHH (兩個(gè)十六進(jìn)制數(shù))
- \uXXXX (四個(gè)八進(jìn)制數(shù))
console.log('1\n2')
// 1
// 2
'\a'
// "a"
'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true
4.2 字符串方法
- 使用數(shù)組的方括號(hào)運(yùn)算符,用來返回某個(gè)位置的字符(位置編號(hào)從0開始)
- length屬性返回字符串的長度
var s = 'hello';
s[0] // "h"
// 直接對(duì)字符串使用方括號(hào)運(yùn)算符
'hello'[1] // "e"
s.length // 5
4.3 Base64 轉(zhuǎn)碼
文本里面包含一些不可打印的符號(hào)拓劝,比如 ASCII 碼0到31的符號(hào)都無法打印出來雏逾,這時(shí)可以使用 Base64 編碼,將它們轉(zhuǎn)成可以打印的字符郑临。另一個(gè)場景是栖博,有時(shí)需要以文本格式傳遞二進(jìn)制數(shù)據(jù),那么也可以使用 Base64 編碼厢洞。
所謂 Base64 就是一種編碼方法仇让,可以將任意值轉(zhuǎn)成0~9典奉、A~Z、a-z丧叽、+和/這64個(gè)字符組成的可打印字符卫玖。使用它的主要目的,不是為了加密踊淳,而是為了不出現(xiàn)特殊字符骇笔,簡化程序的處理。
i. JavaScript 原生提供兩個(gè) Base64 相關(guān)的方法嚣崭。
- btoa():ASCII碼字符轉(zhuǎn)為 Base64 編碼;
- atob():Base64 編碼轉(zhuǎn)為原來的值懦傍。
ii. 非ASCII碼字符轉(zhuǎn)為Base64編碼雹舀,必須中間插入一個(gè)轉(zhuǎn)碼環(huán)節(jié)。
function b64Encode(str) {
return btoa(encodeURIComponent(str));
}
function b64Decode(str) {
return decodeURIComponent(atob(str));
}
b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"
5. 對(duì)象
5.1 概述
通常粗俱,數(shù)值说榆、字符串、布爾值這三種類型寸认,合稱為不能再細(xì)分的原始類型签财,對(duì)象類型往往是由多個(gè)原始類型的值的組成,可稱為合成類型偏塞。
對(duì)象類型的組成部分的本質(zhì)是無序鍵值對(duì)唱蒸,‘鍵名’都是字符串,也稱為屬性灸叼,當(dāng)為合法標(biāo)識(shí)符時(shí)神汹,則字符串引號(hào)可省略;‘鍵值’可以是任何數(shù)據(jù)類型古今,也可為函數(shù)屁魏。
5.2 表達(dá)式還是語句
如果沒有圓括號(hào),eval將其理解為一個(gè)代碼塊捉腥;加上圓括號(hào)以后氓拼,就理解成一個(gè)對(duì)象。
eval('{foo: 123}') // 123
eval('({foo: 123})') // {foo: 123}
5.3 對(duì)象的引用
如果不同的變量名指向同一個(gè)對(duì)象抵碟,那么它們都是這個(gè)對(duì)象的引用桃漾,也就是說指向同一個(gè)內(nèi)存地址。修改其中一個(gè)變量拟逮,會(huì)影響到其他所有變量呈队。
5.4 屬性操作
i. 讀取屬性
點(diǎn)運(yùn)算符和方括號(hào)運(yùn)算符讀取對(duì)象屬性,若方括號(hào)運(yùn)算符內(nèi)標(biāo)識(shí)符無引號(hào)唱歧,則標(biāo)識(shí)符表示一變量宪摧,而非字符串粒竖;
查看一個(gè)對(duì)象本身的所有屬性,可以使用Object.keys方法几于;
var obj = {
key1: 1,
key2: 2
};
Object.keys(obj);
// ['key1', 'key2']
- for...in循環(huán)用來遍歷一個(gè)對(duì)象的全部屬性蕊苗。
它遍歷的是對(duì)象所有可遍歷(enumerable)的屬性,會(huì)跳過不可遍歷的屬性沿彭。
它不僅遍歷對(duì)象自身的屬性朽砰,還遍歷繼承的屬性。
var obj = {a: 1, b: 2, c: 3};
for (var i in obj) {
console.log(obj[i]);
}
// 1
// 2
// 3
- in運(yùn)算符喉刘,用于檢查對(duì)象是否包含某個(gè)屬性(注意瞧柔,檢查的是鍵名,不是鍵值)睦裳,如果包含就返回true造锅,否則返回false。
ii. 增加屬性
允許屬性的“后綁定”廉邑,使用點(diǎn)運(yùn)算符和方括號(hào)運(yùn)算符來讀取“后綁定”對(duì)象屬性哥蔚。
iii. 刪除屬性
delete命令用于刪除對(duì)象的屬性,刪除成功后返回true蛛蒙。
三糙箍、數(shù)據(jù)轉(zhuǎn)換
1. 強(qiáng)制轉(zhuǎn)換
1.1 Number()、parseInt()牵祟、parseFloat()
i. 原始類型值
對(duì)于Number()深夯,數(shù)值和字符串整體轉(zhuǎn)換為數(shù)值,基本上只要有一個(gè)字符無法轉(zhuǎn)成數(shù)值诺苹,整個(gè)字符串就會(huì)被轉(zhuǎn)為NaN塌西。布爾值true和false轉(zhuǎn)換為1和0,undefined和null轉(zhuǎn)換為NaN和0筝尾,
對(duì)于parseInt()捡需,將參數(shù)(不能識(shí)別符合科學(xué)計(jì)數(shù)法字符串)轉(zhuǎn)為字符串,返回字符串有效位的整數(shù)筹淫,無有效位返回NaN站辉。
parseInt(字符串,進(jìn)制)
- 字符串的進(jìn)制由進(jìn)制參數(shù)和字符串首位決定损姜,進(jìn)制參數(shù)會(huì)被自動(dòng)轉(zhuǎn)為一個(gè)整數(shù)(2到36之間)饰剥,進(jìn)制參數(shù)是0、undefined和null摧阅,則直接忽略汰蓉,返回該值對(duì)應(yīng)的十進(jìn)制數(shù),字符串首位是OX棒卷,則默認(rèn)進(jìn)制參數(shù)為十六進(jìn)制顾孽,O為首字符串參數(shù)祝钢,0將會(huì)被忽略,則默認(rèn)進(jìn)制參數(shù)為十進(jìn)制若厚;
- 如果字符串包含對(duì)于指定進(jìn)制無意義的字符拦英,則從最高位開始,只返回可以轉(zhuǎn)換的數(shù)值测秸。如果最高位無法轉(zhuǎn)換疤估,則直接返回NaN;
對(duì)于parseFloat()霎冯,將參數(shù)(能識(shí)別符合科學(xué)計(jì)數(shù)法字符串)轉(zhuǎn)為字符串铃拇,返回字符串有效位的小數(shù),無有效位返回NaN沈撞;
parseInt慷荔,parseFloat和Number函數(shù)都會(huì)自動(dòng)過濾一個(gè)字符串前導(dǎo)和后綴的空格。
parseInt('\t\v\r12.34\n') // 12
Number('\t\v\r12.34\n') // 12.34
對(duì)于布爾值关串、null和undefined的轉(zhuǎn)換值區(qū)別如下。
數(shù)值轉(zhuǎn)換 | true | false | null | undefined |
---|---|---|---|---|
Number() | 1 | 0 | 0 | NaN |
parseInt() | NaN | NaN | NaN | NaN |
parseFloat() | NaN | NAN | NaN | NaN |
ii. 對(duì)象
Number()监徘、parseInt()晋修、parseFloat()會(huì)將對(duì)象轉(zhuǎn)換為原始數(shù)據(jù)類型,再使用Number函數(shù)將原始數(shù)據(jù)類型轉(zhuǎn)為數(shù)值凰盔。
對(duì)象轉(zhuǎn)換為原始數(shù)據(jù)類型過程具體為先調(diào)用對(duì)象自身的valueOf方法墓卦,使對(duì)象能返回原始類型的值,否則改為調(diào)用對(duì)象自身的toString方法户敬,返回原始類型的值落剪,如果toString方法返回的還是對(duì)象,就報(bào)錯(cuò)尿庐。
1.2 String()忠怖、toString()
i. 原始類型的值
String()函數(shù)和toString()方法功能范圍:
數(shù)值:轉(zhuǎn)為相應(yīng)的字符串,額外地抄瑟,toString()方法可傳入二凡泣、八、十六數(shù)值或字符串的進(jìn)制參數(shù)皮假;
字符串:轉(zhuǎn)換后還是原來的值鞋拟;
布爾值:true轉(zhuǎn)為字符串"true",false轉(zhuǎn)為字符串"false"惹资;
undefined:String()函數(shù)轉(zhuǎn)為字符串"undefined"贺纲,但無toString()方法;
null:String()函數(shù)轉(zhuǎn)為字符串"null"褪测,但無toString()方法猴誊。
ii. 對(duì)象
String()會(huì)將對(duì)象轉(zhuǎn)換為原始類型的值潦刃,和Number()相反,String()先調(diào)用toString稠肘,后調(diào)用valueOf福铅。
String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"
1.3 Boolean()
除了undefined,null项阴,false滑黔,0,NaN环揽,""或''(空字符串)六個(gè)值被轉(zhuǎn)為false略荡,其他都是true,包括空數(shù)組([])和空對(duì)象({})歉胶。
2. 自動(dòng)轉(zhuǎn)換
自動(dòng)轉(zhuǎn)換的規(guī)則是:預(yù)期是布爾值汛兜、數(shù)值、字符串的地方通今,會(huì)分別自動(dòng)調(diào)用Boolean粥谬、Number和String函數(shù)進(jìn)行轉(zhuǎn)換。
2.1 自動(dòng)轉(zhuǎn)換為布爾值
i. 下列運(yùn)算符會(huì)返回布爾值辫塌;
兩元邏輯運(yùn)算符: && (And)漏策,|| (Or);
前置邏輯運(yùn)算符: ! (Not)臼氨,!!(等價(jià)Boolean())掺喻;
相等運(yùn)算符:===,!==储矩,==感耙,!=;
比較運(yùn)算符:>持隧,>=即硼,<,<=屡拨。
ii. 程序流程的控制里谦絮,判斷條件會(huì)自動(dòng)會(huì)返回布爾值。
if ([]) {
console.log('true');
}
// true
if ({}) {
console.log('true');
}
// true
2.2 自動(dòng)轉(zhuǎn)換為字符串
主要發(fā)生在字符串的加法運(yùn)算時(shí)洁仗。當(dāng)一個(gè)值為字符串层皱,另一個(gè)值為非字符串,則后者轉(zhuǎn)為字符串赠潦。
2.3 自動(dòng)轉(zhuǎn)換為數(shù)值
除了加法運(yùn)算符(+)有可能把運(yùn)算子轉(zhuǎn)為字符串叫胖,其他運(yùn)算符都會(huì)把兩側(cè)運(yùn)算子自動(dòng)轉(zhuǎn)成數(shù)值。