摘要:操作符剛說(shuō)完,肯定又有人想用,但是,真的有用嗎操作符用來(lái)比較兩個(gè)操作數(shù)的構(gòu)造函數(shù),運(yùn)算符與運(yùn)算符相似,用于識(shí)別正在處理的對(duì)象的類(lèi)型。
題目
實(shí)現(xiàn)一個(gè)函數(shù)typeof(),輸入一個(gè)數(shù)據(jù),返回?cái)?shù)據(jù)的基本類(lèi)型。
如:
typeof([]) => array typeof({}) => object typeof("") => string 等等解析
由于javascript這門(mén)語(yǔ)言輝(keng)煌(die)的歷史,所以連這種簡(jiǎn)單的需求都需要自己來(lái)實(shí)現(xiàn),唉,說(shuō)多了,都是淚啊。
這兒題目相對(duì)來(lái)說(shuō)應(yīng)該是比較簡(jiǎn)單的,但是也是有不少坑,想要真正實(shí)現(xiàn)的很好,還是需要用到不少知識(shí)的。
一開(kāi)始,肯定有人想到使用typeof,顧名思義嘛,就是判斷數(shù)據(jù)的類(lèi)型,但是,可是,實(shí)際真的是這樣嗎?
typeof操作符typeof 操作符(和 instanceof 一起)或許是 JavaScript 中最大的設(shè)計(jì)缺陷, 因?yàn)閹缀醪豢赡軓乃鼈兡抢锏玫较胍慕Y(jié)果。 --javascript秘密花園
盡管instanceof 還有一些極少數(shù)的應(yīng)用場(chǎng)景,typeof 只有一個(gè)實(shí)際的應(yīng)用,就是用來(lái)檢測(cè)一個(gè)對(duì)象是否已經(jīng)定義或者是否已經(jīng)賦值,而這個(gè)應(yīng)用卻不是用來(lái)檢查對(duì)象的類(lèi)型。(好吧,這個(gè)其實(shí)貌似也并沒(méi)有什么卵用。。。)
在下面表格中,Type 一列表示 typeof 操作符的運(yùn)算結(jié)果。其中,JavaScript 標(biāo)準(zhǔn)文檔中定義: [[Class]] 的值只可能是下面12個(gè)字符串中的一個(gè): Arguments, Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, String??梢钥吹?,這個(gè)值在大多數(shù)情況下都返回 "object"。
Value | Class | Type |
---|---|---|
"foo" | String | string |
new String("foo") | String | object |
1.2 | Number | number |
new Number(1.2) | Number | object |
true | Boolean | boolean |
new Boolean(true) | Boolean | object |
new Date() | Date | object |
new Error() | Error | object |
[1,2,3] | Array | object |
new Array(1, 2, 3) | Array | object |
new Function("") | Function | function |
/abc/g | RegExp | object (function in Nitro/V8) |
new RegExp("meow") | RegExp | object (function in Nitro/V8) |
{} | Object | object |
new Object() | Object | object |
##### 測(cè)試為定義變量
typeof foo !== "undefined"
上面代碼會(huì)檢測(cè) foo 是否已經(jīng)定義;如果沒(méi)有定義而直接使用會(huì)導(dǎo)致 ReferenceError 的異常。 這是 typeof 唯一有用的地方。
instanceof 操作符剛說(shuō)完,typeof,肯定又有人想用instanceof,但是,instanceof真的有用嗎?
instanceof 操作符用來(lái)比較兩個(gè)操作數(shù)的構(gòu)造函數(shù),instanceof 運(yùn)算符與 typeof 運(yùn)算符相似,用于識(shí)別正在處理的對(duì)象的類(lèi)型。具體的可以看看這個(gè)JavaScript instanceof 運(yùn)算符深入剖析。
因此,instanceof在判斷一個(gè)對(duì)象是不是一個(gè)類(lèi)的實(shí)例只有在比較自定義的對(duì)象時(shí)才有意義。 如果用來(lái)比較內(nèi)置類(lèi)型,將會(huì)和 typeof 操作符 一樣用處不大。
function Foo() {} function Bar() {} Bar.prototype = new Foo(); new Bar() instanceof Bar; // true new Bar() instanceof Foo; // true // 如果僅僅設(shè)置 Bar.prototype 為函數(shù) Foo 本身,而不是 Foo 構(gòu)造函數(shù)的一個(gè)實(shí)例。 Bar.prototype = Foo; new Bar() instanceof Foo; // falseinstanceof 比較內(nèi)置類(lèi)型
但是,不是通過(guò)構(gòu)造函數(shù)創(chuàng)建的對(duì)象使用instanceof比較,那得到的,可能就不是你想要的結(jié)果。
new String("foo") instanceof String; // true new String("foo") instanceof Object; // true "foo" instanceof String; // false "foo" instanceof Object; // false注意
還有有一點(diǎn)需要注意,instanceof 用來(lái)比較屬于不同 JavaScript 上下文的對(duì)象(比如,瀏覽器中不同的文檔結(jié)構(gòu))時(shí)將會(huì)出錯(cuò), 因?yàn)樗鼈兊臉?gòu)造函數(shù)不會(huì)是同一個(gè)對(duì)象。
看到這里,是不是很震驚?你所知道的知道的方法,都是錯(cuò)的。。。唉,當(dāng)初我知道了這個(gè)也是淚流滿(mǎn)面啊。。。
解決方法 Object.prototype.toStringjavascript對(duì)象的內(nèi)部屬性 [[Class]] 的值就包含有j其對(duì)象的類(lèi)型,為了獲取對(duì)象的 [[Class]],我們需要使用定義在 Object.prototype 上的方法 toString。
function is(type, obj) { var clas = Object.prototype.toString.call(obj).slice(8, -1); return obj !== undefined && obj !== null && clas === type; } is("String", "test"); // true is("String", new String("test")); // true
Object.prototype.toString 返回一種標(biāo)準(zhǔn)格式字符串,所以上例可以通過(guò) slice 截取指定位置的字符串,如下所示:
Object.prototype.toString.call([]) // "[object Array]" Object.prototype.toString.call({}) // "[object Object]" Object.prototype.toString.call(2) // "[object Number]"看看大神的解決方案
如果我沒(méi)記錯(cuò),在jQuery和underscore等庫(kù)中都有判斷數(shù)據(jù)類(lèi)型的函數(shù),可能平時(shí)大家也就用用,沒(méi)有仔細(xì)了解過(guò)它們的底層是怎么實(shí)現(xiàn)的,
我們要會(huì)使用框架,但不要依賴(lài)框架
以后大家再碰到類(lèi)似的問(wèn)題的時(shí)候,不妨查看一下這些成熟框架或庫(kù)的實(shí)現(xiàn)源碼,這里,我拋出jQuery的實(shí)現(xiàn)源碼,拋磚引玉。
var class2type = {} ; "Boolean Number String Function Array Date RegExp Object Error".split(" ").forEach(function(e,i){ class2type[ "[object " + e + "]" ] = e.toLowerCase(); }) ; //當(dāng)然為了兼容IE低版本,forEach需要一個(gè)polyfill,不作細(xì)談了。 function _typeof(obj){ if ( obj == null ){ return String( obj ); } return typeof obj === "object" || typeof obj === "function" ? class2type[ Object.prototype.toString.call(obj) ] || "object" : typeof obj; }結(jié)論:
看源碼是程序員快速成長(zhǎng)的重要方式。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/79512.html
摘要:本文將講解我目前所知道的判斷數(shù)據(jù)類(lèi)型的方法。數(shù)據(jù)類(lèi)型一共有種除了之外的種屬于原始數(shù)據(jù)類(lèi)型。等價(jià)于問(wèn)題四的返回值是什么答案。 本文將講解我目前所知道的判斷JavaScript數(shù)據(jù)類(lèi)型的方法。JavaScript數(shù)據(jù)類(lèi)型一共有7種: Undefined Null Boolean String Symbol Number Object 除了Object之外的6種屬于原始數(shù)據(jù)類(lèi)型。有時(shí),我...
摘要:除和外,所有的數(shù)據(jù)類(lèi)型都是可以轉(zhuǎn)化為對(duì)象,而如果是對(duì)象,就肯定有構(gòu)造函數(shù)。特性因?yàn)楹蜎](méi)有構(gòu)造函數(shù),因此不能用此方法來(lái)判斷。由于同一條原型繼承鏈上的各個(gè)對(duì)象的構(gòu)造函數(shù)都不一樣,因此,此方法可以區(qū)分開(kāi)繼承鏈上的各個(gè)自定義數(shù)據(jù)類(lèi)型。 typeof 用法示例 var arr = []; typeof arr; //object typeof(arr); //object typeo...
摘要:對(duì)象類(lèi)型常見(jiàn)的有,,,正則新增自己提供的樂(lè)行判斷如果不對(duì)對(duì)象做嚴(yán)格區(qū)分使用。的實(shí)現(xiàn)使用了原型繼承的表示左表達(dá)式,表示右表達(dá)式,它是用是否等于來(lái)判斷對(duì)象的類(lèi)型的。常見(jiàn)框架和庫(kù)的實(shí)數(shù)據(jù)類(lèi)型判斷測(cè)試這里將的實(shí)現(xiàn)原理抽取出來(lái),用原生實(shí)現(xiàn)。 JavaScript一共有六種數(shù)據(jù)類(lèi)型,分為原始類(lèi)型(又名基本類(lèi)型)和對(duì)象類(lèi)型(又名引用類(lèi)型) 原始類(lèi)型有五種,分別為number,string,boole...
摘要:注意基本變量類(lèi)型不是對(duì)象類(lèi)型,只有基本包裝類(lèi)型才是對(duì)象類(lèi)型。至于顯示的原型,在里用屬性表示,這個(gè)是原型繼承的基礎(chǔ)知識(shí),在這里就不在敘述了。 前言 如果你要開(kāi)發(fā)一個(gè)復(fù)雜的產(chǎn)品,那么肯定少不了使用面向?qū)ο髾C(jī)制,當(dāng)然也避不開(kāi) Javascript 里面的繼承,instanceof 運(yùn)算符是原生 Javascript 語(yǔ)言中用來(lái)判斷實(shí)例繼承的操作符。所以我們有必要深入理解該運(yùn)算符! inst...
摘要:日常工作中經(jīng)常會(huì)有判斷數(shù)據(jù)類(lèi)型的需求,這里簡(jiǎn)單介紹下我平時(shí)判斷數(shù)據(jù)類(lèi)型的幾種方式。當(dāng)使用檢測(cè)基本類(lèi)型時(shí),會(huì)始終返回操作符確實(shí)解決了類(lèi)型判斷的問(wèn)題,但還是有一些不足之處。此外,只能返回,并不能直接返回?cái)?shù)據(jù)的類(lèi)型。 JavaScript中有5種基本數(shù)據(jù)類(lèi)型:undefined,String,Boolean,Number,Null,以及一種復(fù)雜數(shù)據(jù)類(lèi)型Object。日常工作中經(jīng)常會(huì)有判斷數(shù)據(jù)...
摘要:比如我們今天要討論的,在當(dāng)中如何判斷一個(gè)數(shù)組是數(shù)組。在數(shù)組的原型鏈上也能找到構(gòu)造函數(shù)由上面的幾行代碼可以看出,使用運(yùn)算符可以分辨數(shù)組和對(duì)象,可以判斷數(shù)組是數(shù)組。用判斷實(shí)例化的數(shù)組擁有一個(gè)屬性,這個(gè)屬性指向生成這個(gè)數(shù)組的方法。 如果你沒(méi)有注意過(guò)這個(gè)問(wèn)題,那么這個(gè)標(biāo)題應(yīng)該會(huì)讓你感到困惑,判斷數(shù)據(jù)類(lèi)型這么基礎(chǔ)的問(wèn)題能有什么坑呢? 少年,你不能太天真了,我們朝夕面對(duì)的這門(mén)語(yǔ)言,可是JavaSc...
閱讀 2199·2021-11-24 10:26
閱讀 2809·2021-11-23 09:51
閱讀 2919·2021-10-08 10:05
閱讀 1706·2021-09-22 15:18
閱讀 1638·2019-08-29 18:45
閱讀 2154·2019-08-29 18:40
閱讀 3344·2019-08-29 16:16
閱讀 2859·2019-08-29 14:21