判斷某個(gè)對(duì)象是否為Array?

題目:如何判斷一個(gè)js對(duì)象是否是Array,arr為要判斷的對(duì)象爸吮,其中最準(zhǔn)確的方法是制市?
A. typeof(arr)
B. arr instanceof Array
C. arr.toString==='[object Array]';
D. Object.prototype.toString.call(arr) === '[object Array]';

在開(kāi)發(fā)中,我們經(jīng)常需要判斷某個(gè)對(duì)象是否為數(shù)組類型谢肾,在Js中檢測(cè)對(duì)象類型的常見(jiàn)方法都有哪些呢?

typeof操作符

typeof操作符可能返回下列某個(gè)字符串:

  • "undefined" —— 值未定義
  • "boolean"
  • "string"(小寫)
  • "number"
  • "object" —— 這個(gè)值是對(duì)象或者null
  • "function"
typeof []; // "object"
  • 對(duì)于Function时呀, String, Number 晶默,Undefined 等幾種類型的對(duì)象來(lái)說(shuō)谨娜,他完全可以勝任,但是為Array時(shí)磺陡,就會(huì)得到object趴梢。
  • 這是因?yàn)椋簲?shù)組屬于js對(duì)象,用此操作符檢測(cè)只能返回"object"

instanceof操作符

instanceof 運(yùn)算符用來(lái)測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的 prototype 屬性币他。

語(yǔ)法

object instanceof constructor
//object需檢測(cè)對(duì)象
//constructor某個(gè)構(gòu)造函數(shù)

描述
instanceof 運(yùn)算符用來(lái)檢測(cè) constructor.prototype是否存在于參數(shù) object 的原型鏈上坞靶。

深入理解instanceof

instanceof和多全局對(duì)象(多個(gè)frame或多個(gè)window之間的交互)
在瀏覽器中,我們的腳本可能需要在多個(gè)窗口之間進(jìn)行交互蝴悉。多個(gè)窗口意味著多個(gè)全局環(huán)境彰阴,不同的全局環(huán)境擁有不同的全局對(duì)象,從而擁有不同的內(nèi)置類型構(gòu)造函數(shù)拍冠。這可能會(huì)引發(fā)一些問(wèn)題尿这。
比如,表達(dá)式[] instanceof window.frames[0].Array會(huì)返回false庆杜,因?yàn)?Array.prototype !== window.frames[0].Array.prototype射众,因此你必須使用 Array.isArray(myObj) 或者 Object.prototype.toString.call(myObj) === "[object Array]"來(lái)判斷myObj是否是數(shù)組。

  • 栗子
//1.正常情況下
[] instanceof Array   //true

//2.多個(gè)frame交互時(shí)——就會(huì)產(chǎn)生大問(wèn)題了晃财。
var iframe = document.createElement('iframe');    
document.body.appendChild(iframe);    
xArray = window.frames[window.frames.length-1].Array;       
var arr = new xArray("1","2","3","4","5");//這個(gè)寫法IE大哥下是不支持的叨橱,F(xiàn)F下才有       
alert(arr instanceof Array); // false 
alert(arr.constructor === Array); // false  

//3.萬(wàn)全判斷方法
Array.isArray(arr);  // true
Object.prototype.toString.call(arr) === "[object Array]" ;   //true
  • 當(dāng)檢測(cè)Array實(shí)例時(shí), Array.isArray 優(yōu)于 instanceof,因?yàn)锳rray.isArray能檢測(cè)iframes.

Object.prototype.toString.call(obj)

ECMA-262 寫道
Object.prototype.toString( ) When the toString method is called, the following steps are taken:

  1. Get the [[Class]] property of this object.
  2. Compute a string value by concatenating the three strings “[object “, Result (1), and “]”.
  3. Return Result (2)

上面的規(guī)范定義了Object.prototype.toString的行為:
首先,取得對(duì)象的一個(gè)內(nèi)部屬性[[Class]]断盛,然后依據(jù)這個(gè)屬性罗洗,返回一個(gè)類似于"[object Array]"的字符串作為結(jié)果(看過(guò)ECMA標(biāo)準(zhǔn)的應(yīng)該都知道,[[]]用來(lái)表示語(yǔ)言內(nèi)部用到的钢猛、外部不可直接訪問(wèn)的屬性栖博,稱為“內(nèi)部屬性”)。利用這個(gè)方法厢洞,再配合call,我們可以取得任何對(duì)象的內(nèi)部屬性[[Class]]典奉,然后把類型檢測(cè)轉(zhuǎn)化為字符串比較躺翻,以達(dá)到我們的目的。還是先來(lái)看看在ECMA標(biāo)準(zhǔn)中Array的描述吧卫玖。

ECMA-262 寫道
new Array([ item0[, item1 [,…]]])
The [[Class]] property of the newly constructed object is set to “Array”

  • 于是:
if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}
  • 分析:

call改變toString的this引用為待檢測(cè)的對(duì)象公你,返回此對(duì)象的字符串表示,然后對(duì)比此字符串是否是'[object Array]'假瞬,以判斷其是否是Array的實(shí)例陕靠。也許你要問(wèn)了迂尝,為什么不直接o.toString()?嗯剪芥,雖然Array繼承自O(shè)bject垄开,也會(huì)有toString方法,但是這個(gè)方法有可能會(huì)被改寫而達(dá)不到我們的要求税肪,而Object.prototype則是老虎的屁股溉躲,很少有人敢去碰它的,所以能一定程度保證其“純潔性”:)

與前面幾個(gè)方案不同益兄,這個(gè)方法很好的解決了跨frame對(duì)象構(gòu)建的問(wèn)題锻梳,經(jīng)過(guò)測(cè)試,各大瀏覽器兼容性也很好净捅,可以放心使用疑枯。一個(gè)好消息是,很多框架蛔六,比如jQuery荆永、Base2等等,都計(jì)劃借鑒此方法以實(shí)現(xiàn)某些特殊的古今,比如數(shù)組屁魏、正則表達(dá)式等對(duì)象的類型判定,不用我們自己寫了捉腥。

另外ECMA已經(jīng)換成這樣的寫法:

isArray : function(v){
   return toString.apply(v) === '[object Array]';
 }

參考博文:
js如何判斷一個(gè)對(duì)象是不是Array氓拼?
Array.isArray()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市抵碟,隨后出現(xiàn)的幾起案子桃漾,更是在濱河造成了極大的恐慌,老刑警劉巖拟逮,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撬统,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡敦迄,警方通過(guò)查閱死者的電腦和手機(jī)恋追,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)罚屋,“玉大人苦囱,你說(shuō)我怎么就攤上這事∑⒚停” “怎么了撕彤?”我有些...
    開(kāi)封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)猛拴。 經(jīng)常有香客問(wèn)我羹铅,道長(zhǎng)蚀狰,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任职员,我火速辦了婚禮麻蹋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘廉邑。我一直安慰自己哥蔚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布蛛蒙。 她就那樣靜靜地躺著糙箍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪牵祟。 梳的紋絲不亂的頭發(fā)上深夯,一...
    開(kāi)封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音诺苹,去河邊找鬼咕晋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛收奔,可吹牛的內(nèi)容都是我干的掌呜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼坪哄,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼质蕉!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起翩肌,我...
    開(kāi)封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤模暗,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后念祭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體兑宇,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年粱坤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了隶糕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡站玄,死狀恐怖若厚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蜒什,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布疤估,位于F島的核電站灾常,受9級(jí)特大地震影響霎冯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜钞瀑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一沈撞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雕什,春花似錦缠俺、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至偿警,卻和暖如春躏救,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背螟蒸。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工盒使, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人七嫌。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓少办,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親诵原。 傳聞我的和親對(duì)象是個(gè)殘疾皇子英妓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

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