數據類型檢測有四種辦法,咱們要清楚的知道每一種方法的特色和不足,以及在真實項目中的應用場景javascript
基本數據類型檢測-> 確定是檢測一個數據類型,js 中數據類型 三大類java
基本數據類型
引用數據類型
symbol 建立惟一值
複製代碼
數據類型檢測四種方式:數組
typeof
instanceof
constructor
Object.prototype.toString.call()
複製代碼
typeof
markdown
/* * typeof:用來檢測數據類型的運算符 * typeof [value] * @return * 首先是個字符串 * 字符串中包含對應的數據類型,例如:"number"、"object"、"undefined"、"function"、"boolean"、"symbol"... * @侷限性 * typeof null =>"object" * 不能具體區分對象數據類型的值(沒法檢測是正則仍是數組等) * typeof [] =>"object" * typeof {} =>"object" * typeof /^$/ =>"object" * @優點 * 使用方便,因此在真實項目中,咱們也會大量應用它來檢測,尤爲是在檢測基本類型值(除null以外)和函數類型值的時候,它仍是很方便的 */ /* function func(n, m, callback) { /!* 形參賦值默認值 *!/ //=>ES6: func(n = 0, m = 0) //=>檢測形參的值是否爲UNDEFINED // n === undefined ? n = 0 : null; // typeof m === "undefined" ? m = 0 : null; //=>基於邏輯或和邏輯與處理(瑕疵:不單單是不傳賦值默認值,若是傳遞的值是假也會處理成爲默認值) // n = n || 0; // m = m || 0; /!* 回調函數執行 *!/ // typeof callback === "function" ? callback() : null; // callback && callback(); //=>瑕疵:傳遞的爲真便可執行,不必定是一個函數,這樣寫是開發者內心已經知道,要否則不傳,要傳就是一個函數 } func(10, 20, function anonymous() {}); */ 複製代碼
instanceof
函數
/* * instanceof:本意是用來檢測實例是否隸屬於某個類的運算符,咱們基於這樣的方式,也能夠用來作某些數據類型的檢測,例如:數組、正則等 * @侷限性 * 不能處理基本數據類型值 * 只要在當前實例的原型鏈(__proto__)中出現過的類,檢測結果都是true(用戶可能會手動修改原型鏈的指向:example.__proto__ 或者 在類的繼承中 等狀況) */ // function func() { // // arguments:類數組 // // arguments.__proto__ = Array.prototype; // // console.log(arguments instanceof Array); //=>true // } // func(); // let arr = [], // reg = /^$/, // obj = {}; // console.log(arr instanceof Array); //=>true // console.log(reg instanceof Array); //=>false // console.log(arr instanceof Object); //=>true // console.log(obj instanceof Array); //=>false // console.log(1 instanceof Number); //=>false //=>建立值的兩種方式(無論哪一種方式都是所屬類的實例) //字面量:let n = 12; //構造函數:let m = new Number('12'); 複製代碼
constructor
this
/* * constructor:構造函數 * @原理:在類的原型上通常都會帶有CONSTRUCTOR屬性,存儲當前類自己,咱們也是利用這一點,獲取某的實例CONSTRUCTOR屬性值,驗證是否爲所屬的類,從而進行數據類型檢測 * @侷限性:CONSTRUCTOR屬性值太容易被修改了 */ // let n = 12, // arr = []; // console.log(n.constructor === Number); //=>true // console.log(arr.constructor === Array); //=>true // console.log(arr.constructor === Object); //=>false // arr.constructor = 111; //=>設置私有屬性 // console.log(arr.constructor === Array); //=>false // Func.prototype={}; //=>這樣原型上沒有CONSTRUCTOR屬性(重構了) 複製代碼
Object.prototype.toString.call([value])
spa
/* * Object.prototype.toString.call([value]):調用Object原型上的toString方法,讓方法執行的時候,方法中的this是要檢測的數據類型 ,從而獲取到數據類型所屬類的詳細信息 * @信息的模板 * "[object 所屬類]" ,例如:"[object Array]"... * * 在全部的數據類型類中,他們的原型上都有toString方法,除Object.prototype.toString不是把數據值轉換爲字符串,其他的都是轉爲字符串,而Object原型上的toString是檢測當前實例隸屬類的詳細信息的(檢測數據類型)... * obj.toString() * 1.首先基於原型鏈查找機制,找到Object.prototype.toString * 2.把找到的方法執行,方法中的this -> obj * 3.方法內部把this(obj)的所屬類信息輸出 * =>方法執行,方法中的this是誰,就是檢測誰的所屬類信息 * * 這個方法很強大,全部數據類型隸屬的類信息檢測的一清二楚 * "[object Number]" * String/Boolean/Null/Undefined/Symbol/Object/Array/RegExp/Date/Math/Function... */ // let _obj = {}, // toString = _obj.toString; // console.log(_obj.toString.call(100)); //=>"[object Number]" // console.log(Object.prototype.toString.call(100)); //=>"[object Number]" /* function func(n, m) { return n + m; } let obj1 = {}, obj2 = { name: '珠峯培訓' }; */ // console.log([12, 23].toString()); //=>"12,23" // console.log(/^\d+$/.toString()); //=>"/^\d+$/" // console.log(func.toString()); //=>"function func(n, m) {..." // console.log(obj1.toString()); //=>"[object Object]" // console.log(obj2.toString()); //=>"[object Object]" 複製代碼
以上分析完全部的方法 各類屬性以及優缺點 下面封裝一個萬能的數據類型檢測方式prototype
var _obj = { isNumeric: "Number", isBoolean: 'Boolean', isString: 'String', isNull: 'Null', isUndefined: 'Undefined', isSymbol: 'Symbol', isPlainObject: 'Object', isArray: 'Array', isRegExp: 'RegExp', isDate: 'Date', isFunction: "Function", isWindow: 'Window' }, _toString = _obj.toString, _type = {}; for (var key in _obj) { if (!_obj.hasOwnProperty(key)) break; //-》 判斷私有的可枚舉屬性 _type[key] = (function () var reg = new RegExp("^\\[object " + _obj[key] + "\\]$"); return function anonymous(val) { return reg.test(_toString.call(val)); } })(); } 複製代碼
此方法可直接用於真實項目code