JavaScript的數(shù)據(jù)類型及判斷

banner

最近自己回歸基礎(chǔ)看了下javascript的相關(guān)知識(shí)點(diǎn)丈攒,想著看都看了,寫出來(lái)記錄下足跡也是一件好事授霸,遂記錄~

還有還有巡验,哪位大佬有廣州前端開發(fā)工程師的機(jī)會(huì)推薦一下嗎,簡(jiǎn)歷可以戳blog下的resume.png碘耳,我請(qǐng)你吃糖????

javascript中有兩種類型显设,一種是基本數(shù)據(jù)類型,一種是引用類型辛辨。

基本類型

基本數(shù)據(jù)類型捕捂,也稱為簡(jiǎn)單數(shù)據(jù)類型,在ES5中有以下五種:Undefined斗搞、Null指攒、Boolean、Number和String僻焚,在ES6中新增了一種簡(jiǎn)單的數(shù)據(jù)類型Symbol允悦。

Undefined類型

Undefined類型只有一個(gè)值undefined。在進(jìn)行相關(guān)變量定義的時(shí)候虑啤,未賦值的情況下隙弛,默認(rèn)是賦值為undefined了。但是也是有些特殊的情況下會(huì)報(bào)錯(cuò)的狞山。情況我大致羅列下:

# 情況1??:變量聲明了全闷,但是沒(méi)有賦值
var message;
console.log(message); // undefined

# 情況2??:變量聲明并賦值了,但是在console運(yùn)行之后
console.log(message); // undefined
var message = 'find a frontend job in Canton!';

# 情況3??:變量沒(méi)聲明萍启,報(bào)引用報(bào)錯(cuò)
// var message;
console.log(message); // Uncaught ReferenceError: message is not defined

# 情況4??:不通過(guò)var聲明室埋,直接寫變量,報(bào)引用錯(cuò)誤
message; // 不等價(jià) var message;
console.log(message); // Uncaught ReferenceError: message is not defined

# 情況5??:不通過(guò)var聲明伊约,直接寫變量賦值
message = 'find a frontend job in Canton!'; // 默認(rèn)在message前添加了var
console.log(message); // find a frontend job in Canton!

# 情況6??:不通過(guò)var聲明姚淆,直接寫賦值,但是在console運(yùn)行之后屡律,報(bào)引用錯(cuò)誤
console.log(message);
message = 'find a frontend job in Canton!'; // 相當(dāng)于沒(méi)message變量

上面羅列的是ES5中通過(guò)var聲明的情況腌逢。也許你會(huì)對(duì)情況2??產(chǎn)生疑惑:我都給message賦值了啊,但是打印出undefined超埋,這就有點(diǎn)尷尬了搏讶?

因?yàn)樵趈s中執(zhí)行上下文分為兩個(gè)階段佳鳖,第一個(gè)階段是創(chuàng)建階段,第二個(gè)階段才是執(zhí)行階段媒惕。

上面情況2??的執(zhí)行情況如下:

1. 創(chuàng)建階段:

executionContextObj = {
    scopeChain: { ... },
    variableObject: {
        message: undefined
    },
    this: { ... }
}

2. 執(zhí)行階段:

executionContextObj = {
    scopeChain: { ... },
    variableObject: {
        message: 'find a frontend job in Canton!'
    },
    this: { ... }
}

詳細(xì)的解析可以看下我之前翻譯的一篇文章JS的執(zhí)行上下文和環(huán)境棧是什么系吩?

上面講到的是var妒蔚,我們引入ES6let 和 const來(lái)演示下:

# 情況7??:let聲明變量賦值
let message;
console.log(message); // undefined

# 情況8??:let聲明變量但是不賦值穿挨,在console運(yùn)行之后
console.log(message); // Uncaught ReferenceError: Cannot access 'message' before initialization
let message = 'find a frontend job in Canton!';

# 情況9??:const聲明變量但是不賦值,報(bào)語(yǔ)法錯(cuò)誤
const message;
console.log(message); // Uncaught SyntaxError: Missing initializer in const declaration

let和const改變了var命令會(huì)發(fā)生變量提升的現(xiàn)象肴盏,即變量可以在聲明之前使用科盛,值為undefined。它們改變了這種奇怪的現(xiàn)象菜皂,聲明的變量一定要在聲明之后使用贞绵,否則報(bào)錯(cuò)。

當(dāng)然還有其他聲明變量的方法恍飘,比如function命令等榨崩,這里不一一列舉,只是探討下undefined的值而已~

Null類型

Null類型的值是null章母。從邏輯角度來(lái)看蜡饵,null值表示一個(gè)空對(duì)象指針。

如果定義的變量準(zhǔn)備在將來(lái)用來(lái)保存對(duì)象胳施,那么最好就是將變量初始化為null,而不是其他的數(shù)據(jù)值肢专。這樣舞肆,只要直接檢查null值就可以知道相應(yīng)的變量是否已經(jīng)保存了一個(gè)對(duì)象的引用。如下面的例子:

if(car != null) {
    // 對(duì)car對(duì)象執(zhí)行某些操作
}

undefined值是派生自null值的博杖。雖然兩者在==比較時(shí)候是相等的椿胯,如下:

console.log(null == undefined); // true

當(dāng)變量不確定類型的時(shí)候,可以不用為變量賦值剃根,也就是默認(rèn)賦值undefined了哩盲。但是如果你知道你的變量要保存對(duì)象但是還沒(méi)有真正保存對(duì)象的時(shí)候就要賦值null了。

Boolean類型

Boolean類型在日常生活中使用頻繁了狈醉,其值是truefalse廉油,對(duì)應(yīng)我們口頭的

將布爾值的truefalse轉(zhuǎn)換為數(shù)值的話苗傅,可以用非00數(shù)字表示抒线。

console.log( 1 == true); // true

console.log( 0 == false); // true

如果是恒等的比較方式===,那數(shù)字表示法是要涼涼的~

Number類型

Number類型有二進(jìn)制表示法渣慕,八進(jìn)制表示法嘶炭,十六進(jìn)制表示法和十進(jìn)制表示法抱慌。這里只討論十進(jìn)制表示法,因?yàn)樵谄匠5拈_發(fā)中眨猎,用到十進(jìn)制的情況居多??

這個(gè)類型用來(lái)表示整數(shù)值和浮點(diǎn)數(shù)值(即帶小數(shù)點(diǎn)的值)抑进。

整數(shù)值的基本操作很是簡(jiǎn)單,而且沒(méi)啥bug好說(shuō)睡陪,除非不在Number.MIN_VALUENumber.MAX_VALUE范圍內(nèi)寺渗。帶小數(shù)點(diǎn)的還是要留意下的,比如:

let a = 13.04;
let b = 2.5;
console.log(a + b); // 15.54
console.log(a * b); // 32.599999999999994
console.log(a - b); // 10.54

咦咦宝穗,真是讓人尷尬??户秤,怎么上面代碼中兩個(gè)浮點(diǎn)數(shù)相乘會(huì)出現(xiàn)那么多位的數(shù)字啊,不是等于32.6嗎逮矛?

所以在進(jìn)行浮點(diǎn)數(shù)的運(yùn)算的時(shí)候還是得慎重點(diǎn)鸡号,先轉(zhuǎn)換成整數(shù)計(jì)算,之后再切換回去浮點(diǎn)數(shù)须鼎,比如上面的a * b可以考慮寫成(a * 100 * (b * 10))/1000鲸伴。

當(dāng)你要判斷一個(gè)值是否是數(shù)值,可以使用isNaN來(lái)表示晋控,其返回一個(gè)布爾值汞窗,如下:

console.log(isNaN(NaN)); // true
console.log(isNaN(10)); // false
console.log(isNaN('10'); // false , '10'會(huì)被轉(zhuǎn)化為10
console.log('blue'); // true , 不能轉(zhuǎn)化為數(shù)值
console.log(true); // false, 可被轉(zhuǎn)化為數(shù)值1

還有將非數(shù)值轉(zhuǎn)化為數(shù)值的三個(gè)方法:Number()、parseInt()和parseFloat()赡译。見(jiàn)名思義:

Number()是將傳入的內(nèi)容轉(zhuǎn)換為數(shù)字(整數(shù))或NaN仲吏。但是在轉(zhuǎn)換字符串的時(shí)候比較復(fù)雜,一般用parseInt()居多蝌焚。parseFloat()就是轉(zhuǎn)化成浮點(diǎn)數(shù)的方法啦裹唆。

String類型

String類型也就是字符串類型啦。

字符串類型包含一些特殊的字符字面量只洒,也叫轉(zhuǎn)義序列许帐,用來(lái)表示非打印字符串。比如換行符\n啦毕谴。

在實(shí)際的開發(fā)中成畦,我們需要將數(shù)字類型或?qū)ο箢愋娃D(zhuǎn)換成字符串類型,那么我們可以直接使用toString()方法進(jìn)行操作啦涝开。好吧循帐,這api的東西大家都會(huì)用,就不說(shuō)了??

Symbol類型

Symbol類型是ES6引入的新類型舀武,為了防止對(duì)象中屬性名沖突的問(wèn)題惧浴。

Symbol值通過(guò)Symbol函數(shù)生成。這就是說(shuō)奕剃,對(duì)象的屬性名現(xiàn)在可以有兩種類型衷旅,一種是原來(lái)就有的字符串捐腿,另一種就是新增的Symbol類型。凡是屬性名屬于Symbol類型柿顶,就都是獨(dú)一無(wú)二的茄袖,可以保證不會(huì)與其他屬性名產(chǎn)生沖突。

具體的看下阮一峰的es6入門中Symbol部分嘁锯。

上面說(shuō)到的是6種基本的數(shù)據(jù)類型宪祥,還有一種是引用類型。

引用類型

引用類型:當(dāng)復(fù)制保存對(duì)象的某個(gè)變量時(shí)家乘,操作的是對(duì)象的引用蝗羊,但是在為對(duì)象添加屬性時(shí),操作的是實(shí)際的對(duì)象仁锯。引用類型值指那些可能有多個(gè)值構(gòu)成的對(duì)象耀找。

引用類型有這幾種:Object、Array业崖、RegExp野芒、Date、Function双炕、特殊的基本包裝類型(String狞悲、Number、Boolean)以及單體內(nèi)置對(duì)象(Global妇斤、Math)摇锋。

基本包裝類型這個(gè)有點(diǎn)好玩,咦站超?上面的基本數(shù)據(jù)類型都有String荸恕、Number和Boolean啦,怎么這里還有這些顷编。是的,上面的基本類型是通過(guò)基本包裝類型來(lái)創(chuàng)建的剑刑。如下:

var s1 = 'find a frontend job in Canton';
var s2 = s1.substring(2);

上面的代碼實(shí)際進(jìn)行了下面的步驟:

(1)創(chuàng)建String類型的一個(gè)實(shí)例媳纬;

(2)在實(shí)例中調(diào)用指定的方法;

(3)銷毀這個(gè)實(shí)例施掏。

上面的三個(gè)步驟轉(zhuǎn)化為代碼如下:

var s1 = new String('find a frontend job in Canton');
var s2 = s1.substring(2);
s1 = null;

(正規(guī))的引用類型和基本包裝類型的主要區(qū)別就是對(duì)象的生存期钮惠。使用new操作符創(chuàng)建的引用類型的實(shí)例,在執(zhí)行流離開當(dāng)前作用域之前都一直保存在內(nèi)存中七芭。而自動(dòng)創(chuàng)建的基本包裝類型的對(duì)象素挽,則只存在于下一行代碼的執(zhí)行瞬間,然后立即被銷毀狸驳。這意味著我們不能在運(yùn)行時(shí)為基本類型值添加屬性和方法预明。來(lái)看下下面的例子:

var s1 = 'find a frontend job in Canton';
s1.name = 'jia ming';
console.log(s1.name); // undefined

只能通過(guò)基本包裝類的原型來(lái)添加了缩赛,比如改寫toString方法:

var s1 = 'find a frontend job in Canton';
String.prototype.toString = function() {
    console.log('my name is jia ming');
}
console.log(s1.toString()); // my name is jia ming

嗯~苦口婆心介紹了javascript的數(shù)據(jù)類型,那么下面才是重頭戲撰糠。我們?cè)趯?shí)際的開發(fā)中酥馍,如何識(shí)別不同的數(shù)據(jù)類型呢?

數(shù)據(jù)類型判斷

數(shù)據(jù)類型有上面的7種類型阅酪,其中基本類型是Undefined旨袒、Null、Boolean术辐、Number砚尽、String和Symbol,還有一種引用類型辉词。引用類型又包含比較多種的對(duì)象必孤,比如ObjectArray等较屿。

我們首先想到的是通過(guò)typeof來(lái)判斷隧魄,直接上代碼來(lái)試下吧:

let symbol = Symbol('jia ming');
let str = 'find a frontend job in Canton!';
let flag = true;
let height = 99;
let job;
let obj = null;
console.log(typeof symbol); // symbol
console.log(typeof str); // string
console.log(typeof flag); // boolean
console.log(typeof height); // number
console.log(typeof job); // undefined
console.log(typeof obj); // object

嗯~很ok啦,對(duì)基本的數(shù)據(jù)類型都能判斷到啦隘蝎,這個(gè)null得到的結(jié)果是object购啄,你可以當(dāng)成特殊情況來(lái)處理啦 -- 無(wú)中生有,一生萬(wàn)物嘛嘱么。

我們?cè)賮?lái)看下引用類型打印出來(lái)的是什么東東??

let person = {
    name: 'jia ming',
    info: 'find a frontend job in Canton!',
};
let arr = ['jia ming', 'find a frontend job in Canton!'];
let reg = new RegExp('jia ming', 'g');
let date = new Date();
let fn = () => {
    return 'find a frontend job in Canton!';
}
let math = Math.min(2, 4, 8);
console.log(typeof person); // object
console.log(typeof arr); // object
console.log(typeof reg); // object
console.log(typeof date); // object
console.log(typeof fn); // function
console.log(typeof math); // number

咦咦~著實(shí)讓人尷尬啊狮含,這個(gè)為啥那么多object啊,我的小心臟??曼振。我們只是簡(jiǎn)單通過(guò)typeof校驗(yàn)比較尷尬啊几迄,我們換個(gè)思路,我們來(lái)結(jié)合call改變下上下文對(duì)象冰评,改寫一個(gè)方法進(jìn)行判斷映胁,如下:

let person = {
    name: 'jia ming',
    info: 'find a frontend job in Canton!',
};
let arr = ['jia ming', 'find a frontend job in Canton!'];
let reg = new RegExp('jia ming', 'g');
let date = new Date();
function handleType(obj, type) {
    if(typeof obj === 'object') {
        return Object.prototype.toString.call(obj) === `[object ${type}]`;
    }
    return false;
}
console.log(handleType(person, 'Object')); // true
console.log(handleType(arr, 'Array')); // true
console.log(handleType(reg, 'RegExp')); // true
console.log(handleType(date, 'Date')); // true

美滋滋,可以實(shí)現(xiàn)區(qū)別判斷的哈甲雅〗馑铮可是上面的基本類型中null也是object啊,然后是Math類型的typeof也是number啊抛人,這個(gè)你可以自己做下處理啦。這里就不考慮了~

后話

有哪位大佬推薦下前端開發(fā)的崗位嗎妖枚?base廣州廷臼,關(guān)于我請(qǐng)戳blog下的resume.png。請(qǐng)你吃棒棒糖??

qiaoba

文章首發(fā):https://github.com/reng99/blogs/issues/27

同步掘金:https://juejin.im/post/5cf25097f265da1b8e708733

更多內(nèi)容:https://github.com/reng99/blogs

參考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末眠寿,一起剝皮案震驚了整個(gè)濱河市例嘱,隨后出現(xiàn)的幾起案子雀彼,更是在濱河造成了極大的恐慌,老刑警劉巖源内,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隘冲,死亡現(xiàn)場(chǎng)離奇詭異油坝,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)缭乘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門司蔬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)邑茄,“玉大人,你說(shuō)我怎么就攤上這事俊啼》温疲” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵授帕,是天一觀的道長(zhǎng)同木。 經(jīng)常有香客問(wèn)我,道長(zhǎng)跛十,這世上最難降的妖魔是什么彤路? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮偶器,結(jié)果婚禮上斩萌,老公的妹妹穿的比我還像新娘。我一直安慰自己屏轰,他們只是感情好颊郎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著霎苗,像睡著了一般姆吭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上唁盏,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天内狸,我揣著相機(jī)與錄音,去河邊找鬼厘擂。 笑死昆淡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的刽严。 我是一名探鬼主播昂灵,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了眨补?” 一聲冷哼從身側(cè)響起管削,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撑螺,沒(méi)想到半個(gè)月后含思,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡甘晤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年含潘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片线婚。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡调鬓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酌伊,到底是詐尸還是另有隱情腾窝,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布居砖,位于F島的核電站虹脯,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏奏候。R本人自食惡果不足惜循集,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蔗草。 院中可真熱鬧咒彤,春花似錦、人聲如沸咒精。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)模叙。三九已至歇拆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間范咨,已是汗流浹背故觅。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留渠啊,地道東北人输吏。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像替蛉,于是被迫代替她去往敵國(guó)和親贯溅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子炼杖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容