數據類型檢測有四種辦法,咱們要清楚的知道每一種方法的特色和不足,以及在真實項目中的應用場景javascript
基本數據類型檢測-> 確定是檢測一個數據類型,js 中數據類型 三大類java
基本數據類型
引用數據類型
symbol 建立惟一值
複製代碼
數據類型檢測四種方式:數組
typeof
instanceof
constructor
Object.prototype.toString.call()
複製代碼
typeof
函數
/* * 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
this
/* * 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
spa
/* * 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])
prototype
/* * 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]"
複製代碼
以上分析完全部的方法 各類屬性以及優缺點 下面封裝一個萬能的數據類型檢測方式code
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));
}
})();
}
複製代碼
此方法可直接用於真實項目對象