JS中的数据类型检测

数据类型检测有四种办法,我们要清楚知道每一种方法的特点和不足,以及在真实项目中的应用场景

  • typeof
  • instanceof&constructor
  • Object.prototype.toString.call([value])
  • 封装一个数据类型检测的方法库

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 === “funcion”?callback():null;
    callback&&callback() //瑕疵:传递的为真即可执行,不一定是一个函数,这样写是开发者心里已经知道,要不然不传,要传就是一个函数
 }
 func();
 func(10);
 func(10,20);
 func(10,20,function anonymous(){
 });
/*instanceof:本意是用来检测实例是否隶属于某个类的运算符
,我们基于这样的方式,也可以用来做某些数据类型的检测,例如:数组、正则等
@局限性
    不能处理基本数据类型值:console.log(1 instanceof Number); //false
    只要在当前实例的原型链(__proto__)中出现过的类,检测结果都是true(用户可能会手动修改原型链的指向:example.__proto__ 或者在类的继承中等情况)*/
let arr = [],
	reg = /^$/,
	obj = {};
console.log(arr instanceof Array); //true
console.log(reg instanceof Array); //false
console.log(1 instanceof Number); //false
console.log(arr instanceof Object); //true
console.log(obj instanceof Array); //true
//创建值的两种方式(不管哪种方式都是所属类的实例)
//1.字面量:let n = 12;
//2.构造函数:let m = new Number('12');

function func() {
	//arguments:类数组
	//arguments.__proto__ = Array.prototype;
	console.log(arguments instanceof Array); //true
}
func();
/*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]):调用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...
function func(n,m){
	return n+m;
}
let obj1 = {},
	obj2 = {name:'大笨蛋'},
obj1.toString(); 
console.log([12,23].toString()); //"12,23"
console.log(/^\d+$/.toString()); //"/^\d+$/"
console.log((function anonymous(){}).toString()); //"function anonymous(){}"
console.log(func.toString()); //"function func(n,m){return n+m;}"
console.log(obj1.toString()); //"[object,object]"
console.log(obj2.toString()); //"[object,object]"

let _obj = {};
console.log(_obj.toString.call(100)); //"[object Number]"
console.log(Object.prototype.toString.call(100)); //"[object Number]
/*把一个函数当做实参传递给另外一个函数,在另外一个函数执行的过程中,把传递进来的函数执行,这种机制就是回调函数
@真实场景应用
   AJAX异步请求成功做什么事
   浏览器内置的一些方法支持函数
   插件组件封装中的钩子函数(生命周期函数)*/
let arr = [10,20,30];
//forEach/sort/map/find/filter/some/every/reduce...
arr.forEach((item,index) =>{});
setTimeout(()=>{},1000);
function queryDate(callback){
	$.ajax({
		url:'xxx.json',
		menthod:'get',
		async:true,
		success:result => {
			typeof callback ==='function' ? callback(result):null;
		}
	});
}
queryDate(function anonymous()){
	//data:服务器返回的结果
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值