<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
js是弱型別語言,或者說是動態語言,在定義變數時我們可以不提前宣告變數的型別,也可以在變數宣告後賦予不同型別的值。變數的型別會在程式執行的過程中被確定。對於開發者來說,雖然可以不用頻繁的定義不同的資料型別,但是如果是比較複雜的專案,或者接手他人的專案,發現一個變數到處被使用並且賦予不同型別的值,也許頭都大了。變數型別的不確定還可能出現執行時報錯:xxx is not a function
,根本原因就是不同的資料型別所具有的方法是不一樣的,也許有的大家都有,因此不報錯;但是如果是特有的,或者有差異的,不判斷變數的型別就直接呼叫,就有可能出現生產bug。那麼應該如何才能獲取準確的變數型別呢?
js內建的一個運運算元,返回一個字串,表示運算元的型別。可用於number、string、boolean等值型別,function函數,object等參照型別,如果是判斷物件型別,則只能得到object
,無法得到具體的值。
console.log(typeof ''); // string console.log(typeof (() => {})); // function console.log(typeof Symbol()); // symbol console.log(typeof undefined); // undefined console.log(typeof null); // object console.log(typeof []); // object console.log(typeof {}); // object
我們可以看到,陣列、物件通過typeof
都是返回了object
,無法細分;其中值得注意的是typeof null
結果也是object
。這是因為在js的最初實現中,js中的值是由一個表示型別的標籤以及實際資料值組合表示的。物件型別的標籤是0,我們都知道null
表示空,在大多數平臺下其值為0x00
,因此物件和null
的型別標籤是一樣的。型別標籤一樣,但是null
卻沒有正常物件的屬性以及方法。
instanceof
也是js內建的一個運運算元,用於判斷兩個引數之間是否存在聯絡,實現原理是檢測建構函式的prototype
屬性是否出現在某個範例物件的原型鏈上。如果是,則返回true;否則,返回false。
console.log({} instanceof Array); // false console.log([] instanceof Array); // true console.log({} instanceof Object); // true console.log([] instanceof Object); // true
instanceof
是判斷兩個引數,並不會直接獲取變數的型別,可以通過列舉的方式簡介獲取。
每一個物件都有一個toString()
方法,因為每個物件都會繼承自Object
。可能在大多數人的印象中,toString()
只是用來返回一個字串,並沒有什麼特別的地方,那是因為你看到的toString()
基本上都是被重寫後的,原始的toString()
是可以用來獲取物件的型別的。
舉個例子:
const o = new Object(); o.toString(); // [object Object] const arr = [1,2,3]; // 陣列也會繼承自Object arr.toString(); // '1,2,3',因為陣列重寫了toString
每個物件都能通過Object.prototype.toString.call(thisArg)
或者Object.prototype.toString.apply(thisArg)
來獲取其型別:
console.log(Object.prototype.toString.call(null)); // [object Null] console.log(Object.prototype.toString.call(undefined)); // [object Undefined] console.log(Object.prototype.toString.call([])); // [object Array] console.log(Object.prototype.toString.call({})); // [object Object] console.log(Object.prototype.toString.call(() => {})); // [object Function]
每次都呼叫js內建的API還是有點麻煩,所以我們還是封裝一個函數getType
之前我們也提到了typeof
可以獲取部分資料型別,instanceof
可以用列舉來表示剩下的型別,那麼這兩者結合是不是就可以實現getType
了呢?
function getType(obj) { if (typeof obj === 'object') { if (obj instanceof Array) return 'array'; if (obj instanceof Map) return 'map'; if (obj instanceof Set) return 'set'; if (obj instanceof RegExp) return 'regexp'; // 儘可能列舉型別,最後兜底返回object return 'object' } return (typeof obj); } console.log(getType(null)); // object console.log(getType(undefined)); // undefined console.log(getType('')); // string console.log(getType([])); // array console.log(getType(/a/)); // regexp console.log(getType(new WeakMap())); // object console.log(getType(new WeakSet())); // object
使用此方式雖然可以實現getType
,但是存在弊端;
關於toString()
的用法剛剛已經說了,我們以此來實現一個getType
function getType(obj) { const originType = Object.prototype.toString.call(obj); // 獲取型別。返回格式為[object type],需要提取出type的值 const firstSpaceIndex = originType.indexOf(' '); // 找到第一個空格所在下標 const type = originType.slice(firstSpaceIndex + 1, -1); // 跳過空格,擷取到倒數第一個字元(不含最後一個) return type.toLowerCase(); // 轉換為小寫 } console.log(getType(null)); // null console.log(getType(undefined)); // undefined console.log(getType('')); // string console.log(getType([])); // array console.log(getType(/a/)); // regexp console.log(getType(new WeakMap())); // weakmap console.log(getType(new WeakSet())); // weakset
實現getType
我們也可以藉助於運算元組的方式:
function getType(obj) { const originType = Object.prototype.toString.call(obj); // 獲取型別。返回格式為[object type],需要提取出type的值 const tmpType = originType.split(' ')[1]; // 根據空格分割,並取第二個 const type = tmpType.slice(0, -1); // 從0擷取到倒數第一個字元(不含最後一個) return type.toLowerCase(); // 轉換為小寫 } console.log(getType(null)); // null console.log(getType(undefined)); // undefined console.log(getType('')); // string console.log(getType([])); // array console.log(getType(/a/)); // regexp console.log(getType(new WeakMap())); // weakmap console.log(getType(new WeakSet())); // weakset
兩者實現結果是一致的,基本上實現了我們的既定目標,而且可以獲取到所有的資料型別。不同的是,運算元組比直接操作字串更消耗效能。
實現一個獲取變數型別的方法,其實並不複雜,簡單來說就是使用了內建的API:Object.prototype.toString()
。有時候,往往就是因為過於簡單而被我們忽略,其實越是簡單的方式,才是越有效的。
以上就是詳解JavaScript如何準確獲取任意變數的資料型別的詳細內容,更多關於JavaScript獲取變數資料型別的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45