JS-數(shù)據(jù)類型- typeof/instanceof/Object.prototype.toString

參考文章:數(shù)據(jù)類型

typeof 運(yùn)算符

JavaScript 有三種方法霹购,可以確定一個值到底是什么類型尿贫。

  • typeof運(yùn)算符
  • instanceof運(yùn)算符
  • Object.prototype.toString方法

typeof

typeof運(yùn)算符可以返回一個值的數(shù)據(jù)類型。

  • 數(shù)值、字符串、布爾值分別返回numberstring尖飞、boolean
typeof 123 // "number"
typeof '123' // "string"
typeof false // "boolean"
  • 函數(shù)返回function店雅。
function f() {}
typeof f
// "function"
  • undefined返回undefined政基。
typeof undefined
// "undefined"

利用這一點(diǎn),typeof可以用來檢查一個沒有聲明的變量闹啦,而不報(bào)錯沮明。

v
// ReferenceError: v is not defined

typeof v
// "undefined"

上面代碼中,變量v沒有用var命令聲明窍奋,直接使用就會報(bào)錯荐健。但是,放在typeof后面琳袄,就不報(bào)錯了江场,而是返回undefined

實(shí)際編程中窖逗,這個特點(diǎn)通常用在判斷語句址否。

// 錯誤的寫法
if (v) {
  // ...
}
// ReferenceError: v is not defined

// 正確的寫法
if (typeof v === "undefined") {
  // ...
}
  • 對象返回object
typeof window // "object"
typeof {} // "object"
typeof [] // "object"

typeof缺點(diǎn):上面代碼中碎紊,空數(shù)組([])的類型也是object佑附,這表示在 JavaScript 內(nèi)部,數(shù)組本質(zhì)上只是一種特殊的對象仗考。 typeof 無法區(qū)分數(shù)組和對象帮匾。
這里順便提一下,instanceof運(yùn)算符可以區(qū)分?jǐn)?shù)組和對象痴鳄。

var o = {};
var a = [];

o instanceof Array // false
a instanceof Array // true
  • null返回object。因?yàn)?code>null被認(rèn)為是一個空的對象的引用缸夹。
typeof null // "object"

instanceof

instanceof運(yùn)算符返回一個布爾值痪寻,表示對象是否為某個構(gòu)造函數(shù)的實(shí)例

  • 下面代碼中虽惭,對象v是構(gòu)造函數(shù)Vehicle的實(shí)例橡类,所以返回true
var v = new Vehicle();
v instanceof Vehicle // true
  • instanceof運(yùn)算符的左邊是實(shí)例對象芽唇,右邊是構(gòu)造函數(shù)顾画。
  • instanceof作用:會檢查右邊構(gòu)造函數(shù)的原型對象(prototype)取劫,是否在左邊對象的原型鏈上。因此研侣,下面兩種寫法是等價(jià)的谱邪。
v instanceof Vehicle
// 等同于
Vehicle.prototype.isPrototypeOf(v)

上面代碼中,Object.prototype.isPrototypeOf的含義如下:

var p = {x:1};//定義一個原型對象
var o = Object.create(p);//使用這個原型創(chuàng)建一個對象
p.isPrototypeOf(o);//=>true:o繼承p
Object.prototype.isPrototypeOf(p);//=> true p繼承自O(shè)bject.prototype
  • 由于instanceof檢查整個原型鏈庶诡,因此同一個實(shí)例對象惦银,可能會對多個構(gòu)造函數(shù)都返回true
var d = new Date();
d instanceof Date // true
d instanceof Object // true

上面代碼中末誓,d同時(shí)是DateObject的實(shí)例扯俱,因此對這兩個構(gòu)造函數(shù)都返回true

  • instanceof原理是檢查右邊構(gòu)造函數(shù)的prototype屬性喇澡,是否在左邊對象的原型鏈上迅栅。有一種特殊情況,就是左邊對象的原型鏈上晴玖,只有null對象读存。這時(shí),instanceof判斷會失真窜醉。
var obj = Object.create(null);
typeof obj // "object"
Object.create(null) instanceof Object // false

上面代碼中宪萄,Object.create(null)返回一個新對象obj,它的原型是null(Object.create的詳細(xì)介紹見后文)榨惰。右邊的構(gòu)造函數(shù)Objectprototype屬性拜英,不在左邊的原型鏈上,因此instanceof就認(rèn)為obj不是Object的實(shí)例琅催。但是居凶,只要一個對象的原型不是nullinstanceof運(yùn)算符的判斷就不會失真藤抡。

  • instanceof運(yùn)算符的一個用處侠碧,是判斷值的類型。
var x = [1, 2, 3];
var y = {};
x instanceof Array // true
y instanceof Object // true

上面代碼中缠黍,instanceof運(yùn)算符判斷弄兜,變量x是數(shù)組,變量y是對象瓷式。

缺點(diǎn)instanceof運(yùn)算符只能用于對象(純對象和數(shù)組)替饿,不適用原始類型(Undefined、Null贸典、Boolean视卢、Number 和 String)的值。

var s = 'hello';
s instanceof String // false

上面代碼中廊驼,字符串不是String對象的實(shí)例(因?yàn)樽址皇菍ο螅┚莨苑祷?code>false惋砂。

此外,對于undefinednull绳锅,instanceOf運(yùn)算符總是返回false西饵。

undefined instanceof Object // false
null instanceof Object // false
  • 利用instanceof運(yùn)算符,還可以巧妙地解決榨呆,調(diào)用構(gòu)造函數(shù)時(shí)罗标,忘了加new命令的問題。
function Fubar (foo, bar) {
  if (this instanceof Fubar) {
    this._foo = foo;
    this._bar = bar;
  } else {
    return new Fubar(foo, bar);
  }
}

上面代碼使用instanceof運(yùn)算符积蜻,在函數(shù)體內(nèi)部判斷this關(guān)鍵字是否為構(gòu)造函數(shù)Fubar的實(shí)例闯割。如果不是,就表明忘了加new命令竿拆。

Object.prototype.toString

  • 要想?yún)^(qū)別對象宙拉、數(shù)組、函數(shù)單純使用 typeof 是不行的丙笋。nullArray 的結(jié)果也是 object谢澈,有時(shí)候我們需要的是 "純粹" 的 object 對象。
  • 我們可以通過Object.prototype.toString方法準(zhǔn)確判斷某個對象值屬于哪種內(nèi)置類型御板。在介紹Object.prototype.toString方法之前锥忿,我們先把toString()方法和Object.prototype.toString.call()方法進(jìn)行對比。
var arr=[1,2];

//直接對一個數(shù)組調(diào)用toString()
arr.toString();// "1,2"

//通過call指定arr數(shù)組調(diào)用Object.prototype對象上原始的toString方法
Object.prototype.toString.call(arr); //"[object Array]"

作為繼承的數(shù)組arr重寫了toString方法怠肋,并不是Object.prototype中的toString方法敬鬓。

  • 為什么toString會有不同的作用呢?
    其實(shí)笙各,這里面就涉及到js原型及原型鏈的相關(guān)知識
var arr=[1,2,3];
Object.prototype.toString.call(arr); //"[object Array]"
Array.prototype.toString.call(arr); // "1,2,3"
arr.toString(); // "1,2,3"

看到這里大家都應(yīng)該明白了钉答,其實(shí)只有Object.prototype上的toString才能用來進(jìn)行復(fù)雜數(shù)據(jù)類型的判斷。

  • 簡單解釋一些原型鏈的概念:

我們都知道js中的對象都繼承自Object杈抢,所以當(dāng)我們在某個對象上調(diào)用一個方法時(shí)数尿,會先在該對象上進(jìn)行查找,如果沒找到則會進(jìn)入對象的原型(也就是.prototype)進(jìn)行查找惶楼,如果沒找到右蹦,同樣的也會進(jìn)入對象原型的原型進(jìn)行查找,直到找到或者進(jìn)入原型鏈的頂端Object.prototype才會停止歼捐。

所以何陆,當(dāng)我們使用arr.toString()時(shí),不能進(jìn)行復(fù)雜數(shù)據(jù)類型的判斷窥岩,因?yàn)樗{(diào)用的是Array.prototype.toString。雖然Array也繼承自Object宰缤,但jsArray.prototype上重寫了toString颂翼,而我們通過Object.prototype.toString.call(arr)實(shí)際上是通過原型鏈調(diào)用了Object.prototype.toString晃洒。

  • 精確判斷對象的類型
    JavaScript 中一切都是對象,任何都不例外朦乏,對所有值類型應(yīng)用 Object.prototype.toString.call() 方法結(jié)果如下:
console.log(Object.prototype.toString.call(123)) //[object Number]
console.log(Object.prototype.toString.call('123')) //[object String]
console.log(Object.prototype.toString.call(undefined)) //[object Undefined]
console.log(Object.prototype.toString.call(true)) //[object Boolean]
console.log(Object.prototype.toString.call({})) //[object Object]
console.log(Object.prototype.toString.call([])) //[object Array]
console.log(Object.prototype.toString.call(function(){})) //[object Function]

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末球及,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子呻疹,更是在濱河造成了極大的恐慌吃引,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刽锤,死亡現(xiàn)場離奇詭異镊尺,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)并思,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進(jìn)店門庐氮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宋彼,你說我怎么就攤上這事弄砍。” “怎么了输涕?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵音婶,是天一觀的道長。 經(jīng)常有香客問我莱坎,道長衣式,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任型奥,我火速辦了婚禮瞳收,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘厢汹。我一直安慰自己螟深,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布烫葬。 她就那樣靜靜地躺著界弧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪搭综。 梳的紋絲不亂的頭發(fā)上垢箕,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天,我揣著相機(jī)與錄音兑巾,去河邊找鬼条获。 笑死,一個胖子當(dāng)著我的面吹牛蒋歌,可吹牛的內(nèi)容都是我干的帅掘。 我是一名探鬼主播委煤,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼修档!你這毒婦竟也來了碧绞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤吱窝,失蹤者是張志新(化名)和其女友劉穎讥邻,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體院峡,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兴使,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撕予。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲫惶。...
    茶點(diǎn)故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖实抡,靈堂內(nèi)的尸體忽然破棺而出欠母,到底是詐尸還是另有隱情,我是刑警寧澤吆寨,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布赏淌,位于F島的核電站,受9級特大地震影響啄清,放射性物質(zhì)發(fā)生泄漏六水。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一辣卒、第九天 我趴在偏房一處隱蔽的房頂上張望掷贾。 院中可真熱鬧,春花似錦荣茫、人聲如沸想帅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽港准。三九已至,卻和暖如春咧欣,著一層夾襖步出監(jiān)牢的瞬間浅缸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工魄咕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衩椒,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像毛萌,于是被迫代替她去往敵國和親梢什。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評論 2 361

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

  • 1.通過typeof可以判斷處幾種基本數(shù)據(jù)類型Boolean,number,string,null,undefin...
    舟漁行舟閱讀 647評論 0 1
  • 概述 JavaScript 原生提供Object對象(注意起首的O是大寫)朝聋,本章介紹該對象原生的各種方法。 Jav...
    許先生__閱讀 472評論 0 3
  • 第一章 錯誤處理: 錯誤: 程序運(yùn)行過程中囤躁,導(dǎo)致程序無法正常執(zhí)行的現(xiàn)象(即bug) 現(xiàn)象: 程序一旦出錯冀痕,默認(rèn)會報(bào)...
    fastwe閱讀 1,121評論 0 1
  • ECMAScript關(guān)鍵字 delete do else finally function in instance...
    doudou2閱讀 723評論 0 0
  • https://blog.csdn.net/shlazww/article/details/47375009
    姚興泉閱讀 325評論 0 0