JS的數(shù)據(jù)類型及其檢測


JavaScript 有幾種類型的值艾船?

Javascript 有兩種數(shù)據(jù)類型葵腹,分別是基本數(shù)據(jù)類型和引用數(shù)據(jù)類型高每。其中基本數(shù)據(jù)類型包括 Undefined、Null践宴、Boolean鲸匿、Number、String阻肩、Symbol (ES6 新增带欢,表示獨一無二的值),而引用數(shù)據(jù)類型統(tǒng)稱為 Object 對象烤惊,主要包括對象乔煞、數(shù)組和函數(shù)。接下來我們分別看下兩者的特點柒室。


基本數(shù)據(jù)類型

1.值是不可變的

var?name?=?'java';

name.toUpperCase();?//?輸出?'JAVA'

console.log(name);?//?輸出??'java'

由此可得渡贾,基本數(shù)據(jù)類型的值是不可改變的


2.存放在棧區(qū)

原始數(shù)據(jù)類型直接存儲在棧(stack)中的簡單數(shù)據(jù)段,占據(jù)空間小雄右、大小固定空骚,屬于被頻繁使用數(shù)據(jù),所以放入棧中存儲擂仍。


3.值的比較

var?a?=?1;

var?b?=?true;

console.log(a?==?b);????//?true

console.log(a?===?b);???//?false

== : 只進(jìn)行值的比較,會進(jìn)行數(shù)據(jù)類型的轉(zhuǎn)換囤屹。

=== : 不僅進(jìn)行值得比較,還要進(jìn)行數(shù)據(jù)類型的比較逢渔。


引用數(shù)據(jù)類型

1.值是可變的

var?a={age:20}肋坚;

a.age=21;

console.log(a.age)//21

上面代碼說明引用類型可以擁有屬性和方法复局,并且是可以動態(tài)改變的冲簿。


2.同時保存在棧內(nèi)存和堆內(nèi)存

引用數(shù)據(jù)類型存儲在堆(heap)中的對象,占據(jù)空間大、大小不固定,如果存儲在棧中亿昏,將會影響程序運行的性能峦剔;引用數(shù)據(jù)類型在棧中存儲了指針,該指針指向堆中該實體的起始地址角钩。當(dāng)解釋器尋找引用值時吝沫,會首先檢索其在棧中的地址,取得地址后從堆中獲得實體递礼。



3.比較是引用的比較

當(dāng)從一個變量向另一個變量賦引用類型的值時惨险,同樣也會將存儲在變量中的對象的值復(fù)制一份放到為新變量分配的空間中。

var?a={age:20};

var?b=a;

b.age=21;

console.log(a.age==b.age)//true

上面我們講到基本類型和引用類型存儲于內(nèi)存的位置不同脊髓,引用類型存儲在堆中的對象辫愉,與此同時,在棧中存儲了指針将硝,而這個指針指向正是堆中實體的起始位置恭朗。變量 a 初始化時屏镊,a 指針指向?qū)ο髙age:20}的地址,a 賦值給 b 后,b 又指向該對象{age:20}的地址痰腮,這兩個變量指向了同一個對象而芥。因此,改變其中任何一個變量膀值,都會相互影響棍丐。



此時,如果取消某一個變量對于原對象的引用沧踏,不會影響到另一個變量歌逢。

var?a={age:20};

var?b=a;

a?=?1;

b?//?{age:20}

上面代碼中,a 和 b 指向同一個對象悦冀,然后 a 的值變?yōu)?1趋翻,這時不會對 b 產(chǎn)生影響,b 還是指向原來的那個對象盒蟆。


檢驗數(shù)據(jù)類型

1.typeof

typeof 返回一個表示數(shù)據(jù)類型的字符串,返回結(jié)果包括:number师骗、boolean历等、string、symbol辟癌、object寒屯、undefined、function 等 7 種數(shù)據(jù)類型黍少,但不能判斷 null寡夹、array 等

typeof?Symbol();?//?symbol?有效

typeof?'';?//?string?有效

typeof?1;?//?number?有效

typeof?true;?//boolean?有效

typeof?undefined;?//undefined?有效

typeof?new?Function();?//?function?有效

typeof?null;?//object?無效

typeof?[]?;?//object?無效

typeof?new?Date();?//object?無效

typeof?new?RegExp();?//object?無效

數(shù)組和對象返回的都是 object,這時就需要使用 instanceof 來判斷


2.instanceof

instanceof 是用來判斷 A 是否為 B 的實例厂置,表達(dá)式為:A instanceof B菩掏,如果 A 是 B 的實例,則返回 true,否則返回 false昵济。instanceof 運算符用來測試一個對象在其原型鏈中是否存在一個構(gòu)造函數(shù)的 prototype 屬性智绸。

[]?instanceof?Array;?//true

{}?instanceof?Object;//true

new?Date()?instanceof?Date;//true

new?RegExp()?instanceof?RegExp//true

關(guān)于數(shù)組的類型判斷,還可以用 ES6 新增Array.isArray()

Array.isArray([]);???//?true


instanceof 三大弊端:

對于基本數(shù)據(jù)類型來說访忿,字面量方式創(chuàng)建出來的結(jié)果和實例方式創(chuàng)建的是有一定的區(qū)別的

console.log(1?instanceof?Number)//false

console.log(new?Number(1)?instanceof?Number)//true

從嚴(yán)格意義上來講瞧栗,只有實例創(chuàng)建出來的結(jié)果才是標(biāo)準(zhǔn)的對象數(shù)據(jù)類型值,也是標(biāo)準(zhǔn)的 Number 這個類的一個實例海铆;對于字面量方式創(chuàng)建出來的結(jié)果是基本的數(shù)據(jù)類型值迹恐,不是嚴(yán)謹(jǐn)?shù)膶嵗怯捎?JS 的松散特點卧斟,導(dǎo)致了可以使用 Number.prototype 上提供的方法殴边。

只要在當(dāng)前實例的原型鏈上憎茂,我們用其檢測出來的結(jié)果都是 true。在類的原型繼承中找都,我們最后檢測出來的結(jié)果未必準(zhǔn)確唇辨。

var?arr?=?[1,?2,?3];

console.log(arr?instanceof?Array)?//?true

console.log(arr?instanceof?Object);??//?true

function?fn(){}

console.log(fn?instanceof?Function)//?true

console.log(fn?instanceof?Object)//?true

不能檢測 null 和 undefined

對于特殊的數(shù)據(jù)類型 null 和 undefined,他們的所屬類是 Null 和 Undefined能耻,但是瀏覽器把這兩個類保護(hù)起來了赏枚,不允許我們在外面訪問使用。


3.嚴(yán)格運算符===

只能用于判斷 null 和 undefined晓猛,因為這兩種類型的值都是唯一的饿幅。

var?a?=?null

typeof?a?//?"object"

a?===?null?//?true

undefined 還可以用 typeof 來判斷

var?b?=?undefined;

typeof?b?===?"undefined"?//?true

b?===?undefined?//?true


4.constructor

constructor 作用和 instanceof 非常相似。但 constructor 檢測 Object 與 instanceof 不一樣戒职,還可以處理基本數(shù)據(jù)類型的檢測栗恩。

var?aa=[1,2];

console.log(aa.constructor===Array);//true

console.log(aa.constructor===RegExp);//false

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

var?reg=/^$/;

console.log(reg.constructor===RegExp);//true

console.log(reg.constructor===Object);//false


constructor 兩大弊端:

null 和 undefined 是無效的對象,因此是不會有 constructor 存在的洪燥,這兩種類型的數(shù)據(jù)需要通過其他方式來判斷磕秤。

函數(shù)的 constructor 是不穩(wěn)定的,這個主要體現(xiàn)在把類的原型進(jìn)行重寫捧韵,在重寫的過程中很有可能出現(xiàn)把之前的 constructor 給覆蓋了市咆,這樣檢測出來的結(jié)果就是不準(zhǔn)確的

function?Fn(){}

Fn.prototype?=?new?Array()

var?f?=?new?Fn

console.log(f.constructor)//Array


5.Object.prototype.toString.call()

Object.prototype.toString.call() 最準(zhǔn)確最常用的方式。首先獲取 Object 原型上的 toString 方法再来,讓方法執(zhí)行蒙兰,讓 toString 方法中的 this 指向第一個參數(shù)的值。

關(guān)于 toString 重要補充說明:

1)本意是轉(zhuǎn)換為字符串芒篷,但是某些 toString 方法不僅僅是轉(zhuǎn)換為字符串

2)對于 Number搜变、String,Boolean针炉,Array挠他,RegExp、Date糊识、Function 原型上的 toString 方法都是把當(dāng)前的數(shù)據(jù)類型轉(zhuǎn)換為字符串的類型(它們的作用僅僅是用來轉(zhuǎn)換為字符串的)

3)Object 上的 toString 并不是用來轉(zhuǎn)換為字符串的绩社。


Object 上的 toString 它的作用是返回當(dāng)前方法執(zhí)行的主體(方法中的 this)所屬類的詳細(xì)信息即"[object Object]",其中第一個 object 代表當(dāng)前實例是對象數(shù)據(jù)類型的(這個是固定死的),第二個 Object 代表的是 this 所屬的類是 Object赂苗。

Object.prototype.toString.call('')?;???//?[object?String]

Object.prototype.toString.call(1)?;????//?[object?Number]

Object.prototype.toString.call(true)?;?//?[object?Boolean]

Object.prototype.toString.call(undefined)?;?//?[object?Undefined]

Object.prototype.toString.call(null)?;?//?[object?Null]

Object.prototype.toString.call(new?Function())?;?//?[object?Function]

Object.prototype.toString.call(new?Date())?;?//?[object?Date]

Object.prototype.toString.call([])?;?//?[object?Array]

Object.prototype.toString.call(new?RegExp())?;?//?[object?RegExp]

Object.prototype.toString.call(new?Error())?;?//?[object?Error]

Object.prototype.toString.call(document)?;?//?[object?HTMLDocument]

Object.prototype.toString.call(window)?;?//[object?global]?window是全局對象global的引用


參考資料

1愉耙、【文章】[ JS 進(jìn)階 ] 基本類型 引用類型 簡單賦值 對象引用(推薦)

2、JS 判斷數(shù)據(jù)類型的三種方法

3拌滋、JS 中的數(shù)據(jù)類型及判斷

4朴沿、Javascript 判斷變量類型的陷阱 與 正確的處理方式

5、判斷 JS 數(shù)據(jù)類型的四種方法


關(guān)注公眾號【grain先森】,回復(fù)關(guān)鍵詞 【18福利】赌渣,獲取為你準(zhǔn)備的年終福利魏铅,更多關(guān)鍵詞玩法期待你的探索~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市坚芜,隨后出現(xiàn)的幾起案子览芳,更是在濱河造成了極大的恐慌,老刑警劉巖鸿竖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沧竟,死亡現(xiàn)場離奇詭異,居然都是意外死亡缚忧,警方通過查閱死者的電腦和手機(jī)悟泵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闪水,“玉大人糕非,你說我怎么就攤上這事∏蛴埽” “怎么了朽肥?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長持钉。 經(jīng)常有香客問我鞠呈,道長,這世上最難降的妖魔是什么右钾? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮旱爆,結(jié)果婚禮上舀射,老公的妹妹穿的比我還像新娘。我一直安慰自己怀伦,他們只是感情好脆烟,可當(dāng)我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著房待,像睡著了一般邢羔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上桑孩,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天拜鹤,我揣著相機(jī)與錄音,去河邊找鬼流椒。 笑死敏簿,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惯裕,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼温数,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蜻势?” 一聲冷哼從身側(cè)響起撑刺,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎握玛,沒想到半個月后够傍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡败许,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年王带,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片市殷。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡愕撰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出醋寝,到底是詐尸還是另有隱情搞挣,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布音羞,位于F島的核電站囱桨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏嗅绰。R本人自食惡果不足惜舍肠,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窘面。 院中可真熱鬧翠语,春花似錦、人聲如沸财边。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酣难。三九已至谍夭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間憨募,已是汗流浹背紧索。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留馋嗜,地道東北人齐板。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親甘磨。 傳聞我的和親對象是個殘疾皇子橡羞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,440評論 2 348

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