JS中的數據類型分為三大類:
簡單類型
引用數據類型
symbol 創(chuàng)建唯一值
數據類型檢測四種方式
- typeof
- instanceof
- constructor
- Object.prototype.toString.call()
typeof
語法:typeof [value]
基于 typeof檢測結果
1.首先是一個字符串;
2.字符串中包含對應的類型;
3.字符串中包含對應的數據類型,例如:"number"碰镜、"object"皇帮、"undefined"黔宛、"function"芭梯、"boolean"、"symbol"...
4.因為typeof檢測的結果都是字符串留储,所以只要兩個及兩個以上同時檢測七嫌,最后結果必然是“string”;
typeof 1 // "number"
typeof NaN // "number"
typeof '' // "string"
typeof "24" // "string"
typeof true // "boolean"
typeof false // "boolean"
typeof undefined // "undefined"
typeof null // "object" // null特殊情況,相當于空指針對象;
function fn () {} // typeof fn => "function"
typeof typeof typeof [] // =>typeof [] => "object" =>typeof "object" => "string"
@優(yōu)勢
使用方便店煞,所以在真實項目中蟹演,我們也會大量應用它來檢測,尤其是在檢測基本類型值(除null之外)和函數類型值的時候顷蟀,它還是很方便的
@局限性
1酒请、 typeof null => “object” , 但是null 并不是對象,是空指針對象;
2鸣个、無法細分當前值是普通對象還是數組對象等羞反, 如: 是正則 還是數組
因為只要是對象數據類型,返回的結果都是"object";
instanceof
語法:[實例] instanceof [類]
- 用來檢測某個實例是否屬于這個類(對象類型)
- 屬于返回TRUE,不屬于返回FALSE;
@局限性:
1囤萤、不能處理基本數據類型值
2昼窗、只要在當前實例的原型鏈(proto)中出現(xiàn)過的類,檢測結果都是true(用戶可能會手動修改原型鏈的指向:example.proto 或者 在類的繼承中 等情況)
arr instanceof Object // 都是true
// 如果是基本數據類型 需要通過構造函數方式創(chuàng)建的值(包裝對象) 才能檢測出來
1 instanceof Number // false
let num = new Number(1)
num instanceof Number // true
'' instanceof String // false
let str = new String('hello');
str instanceof String // true
function CreatePerson(name,age){
this.name = name;
this.age = age;
}
CreatePerson('藍藍',15); // this=>window 普通函數執(zhí)行;
let person1 = new CreatePerson('黃黃',12);
person1 instanceof CreatePerson // =>true
constructor
@原理
在類的原型上一般都會帶有CONSTRUCTOR屬性阁将,存儲當前類本身膏秫,我們也是利用這一點,獲取某實例的CONSTRUCTOR屬性值,驗證是否為所屬的類缤削,從而進行數據類型檢測
@局限性
可以去隨意修改對應的constructor值或者是手動給ary增加一個私有的constructor屬性等;
var obj = {}
console.log(obj.constructor === Object) // true
var arr = []
console.log(arr.constructor === Array) // true
console.log(arr.constructor === Object) // false
var date = new Date()
console.log(date.constructor === Date) // true
var reg = /\d+/
console.log(reg.constructor === RegExp) // true
arr.constructor = 111; //=>設置私有屬性
console.log(arr.constructor === Array); //=>false
Func.prototype={}; //=>這樣原型上沒有CONSTRUCTOR屬性(重構了)
Object.prototype.toString.call([value])
"[object 所屬類]" 窘哈,例如:"[object Array]"...
**所有的數據類型上都有toString方法,只有Object原型上的toString是檢測當前實例所屬類的詳細信息的,其它原型的方法僅僅是轉換為字符串;
@原理
1.首先基于原型鏈查找機制亭敢,找到Object.prototype.toString
2.把找到的方法執(zhí)行滚婉,方法中的this -> obj
3.方法內部把this(obj)的所屬類信息輸出
=>方法執(zhí)行,方法中的this是誰帅刀,就是檢測誰的所屬類信息
@優(yōu)勢
所有數據類型隸屬的類信息檢測的一清二楚
String/Boolean/Null/Undefined/Symbol/Object/Array/RegExp/Date/Math/Function...
console.log(Object.prototype.toString.call(1)) // "[object Number]"
console.log(Object.prototype.toString.call('a')) // "[object String]"
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]"
結合每個方法让腹,屬性的優(yōu)缺點,我們來封裝一個簡單的檢測數據類型庫:
let _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 (let key in _obj) {
if (!_obj.hasOwnProperty(key)) break;
let reg = new RegExp("^\\[object " + _obj[key] + "\\]$");
_type[key] = function (val) {
return reg.test(_toString.call(val));
}
}
console.log(_type.isNumeric('ddd')) // =>false