数据类型检测有四种办法,咱们要清楚的知道每一种方法的特色和不足,以及在真实项目中的应用场景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));
}
})();
}
复制代码
此方法可直接用于真实项目对象