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