这是我参加"第四届青训营"笔记创作活动的第3天
数据类型检测
1.typeof
直接在计算机底层基于数据类型的值(二进制)进行检测,
检测的结果返回的是一个字符串,如:typeof NaN ——>“number”、typeof null ——> "object"、typeof [] ——>"object"、typeof /^$/——>"object"、typeof function(){} ——>"function"
对象存储在计算机中,都是以000开始的二进制存储,null也是,所以检测出来的结果是对象,但null实际不是对象,可以理解为浏览器的一个bug。
typeof 普通对象/数组对象/正则对象/日期对象 ——> "object"
typeof的不足:无法区分具体是什么对象。判断简单数据类型时比较好用。
2.instanceof(检测当前实例是否属于这个类)
如:let arr = [] ;
console.log(arr instanceof Array); //true
console.log(arr instanceod Object); //true
底层机制:只要当前类出现在实例的原型链上,结果都是true。
由于我们可以肆意地修改原型的指向,所以检测出来的结果是不准的。
如:function Fn(){this.x = 100;}
Fn.prototype = Object.create(Array.prototype);
let f = new Fn;
console.log( f , f instanceof Array ); //返回的是true,检测结果错误
不能检测基本数据类型!如:console.log( 1 instanceof Number); //false
面试题:自定义一个instanceof的底层代码让它检测结果变准确
//主要思想:实例.__proto__ ===类.prototype
function instance_of(example,classFunc){
let classFuncPrototype = classFunc.prototype,
proto = Object.getPrototypeOf(example); //代表example.__proto__
while(true) {
if(proto === null){
//Object.prototype.__proto__ =>null
return false;
}
if(proto === classFuncPrototype){
//查找过程中发现有,则证明实例是这个类的一个实例
return true ;
}
proto = Object.getPrototype(proto); //找不到就一直向下找,直到Object为止
}
let arr = [];
console.log(instanceof(arr,Array)); //true
console.log(instanceof(arr,RexExp)); //false
console.log(instanceof(arr,Object)); //true
3.constructor
console.log( arr.constructor === Array); //true
console.log( arr.constructor === RegExp); //false
console.log( arr.constructor === Object); //false
constructor看似比instanceof还好用一些(支持基本数据类型),但是constructor可以随便修改,所以也不准。
4.Object.prototype.toString.call([value])
标准检测数据类型的方法:Object.prototype.toString不是转换为字符串,是返回当前实例所属类的信息。
let obj = { name : '祝福' };
obj.toString() ; =>"[ object Object ]"
typeof与toString相结合的方法——toType:
(
function () {
var class2type = {}
var toString = class2type.toString; //=>Object.prototype.toString
//设定数据类型的映射表
['Boolean','Number','String','Function','Array','Date','RegExp','Object','Error',
'Symbol'].forEach(name => {
class2type[`[object ${name}]`] = name.toLowerCase();
});
console.log(class2type);
function toType(obj){
if(obj == null){
// 传递的值是null或者undefined,就返回对应的字符串
return obj + '';
}
// 基本数据类型都采用typeof检测 三目运算
return typeof obj === 'object' || typeof obj === 'function'?
class2type[toString.call(obj)] || 'object':
typeof obj;
}
window.toType = toType; //()()闭包包起来进行封装,然后通过这条语句让外面使用
}
)()