检测方式一、typeof检测类型
基本语法:
typeof [value]
检测结果返回值:
是一个字符串,包裹着对应的数据类型
适用的检测对象和特征:
1.除null的基本数据类型(原始值类型)
2.function类型
3.检测未声明变量返回一个一个"undefined",不报错
4.检测对象类型不能区分
typeof检测原理:按照计算机二进制值来进行检测,检测速度很快
开发运用:
1.检测基本类型(除null类型外)
2.检测function类型
3.检测浏览器兼容性属性
…
// 检测实例
let isNull = null,
num = 122,
str = '8nnn',
bl = true,
ud = undefined,
arr = [22, 'dd'],
fn = () => {},
obj = { ob: 'typeof obj' },
sym = Symbol('您好'),
bgin = 100n;
console.log(typeof isNull); // object
console.log(typeof num); // number
console.log(typeof bl); // boolean
console.log(typeof ud); // undefined
console.log(typeof arr); // object
console.log(typeof fn); // function
console.log(typeof obj); // object
console.log(typeof sym); // symbol
console.log(typeof bgin); // bigint
// 从以上检测实例结果来看:
// typeof无法区分基本类型null以及Array Object等引用类型
// typeof null 结果为object 原因是typeof采用二进制识别,认为object类型都是000开头 而null是64个0组成的二进制 因此被识别为object
检测方式二 、instanceof 检测类型
基本语法:
[value] instanceof [constructor],检测一个值(实例)是否为[constructor]类的实例
检测结果返回值:
检测结果返回一个布尔值,true或者false
检测原理:
1.首先检测[constructor]是否存在Symbol.hasInstance属性方法,存在则执行这个方法 [constructor]Symbol.hasInstance
Symbol.hasInstance 在兼容Es6的浏览器中,Function.prototype上具备Symbol.hasInstance方法,所以可以说是所有函数有Symbol.hasInstance。
2.如果浏览器检测中不存在Symbol.hasInstance属性方法,则 按照原型链进行查找检测的「如果当前类的原型对象,出现在检测值的原型链上,则结果是true」
检测特征:
1.检测对象是否为Object实例,结果都是true,所以无法验证是否为标准普通对象
2.instanceof无法处理原始值类型的检测的「检测结果都是false,原因:原始值不具备__proto__」
3.因为原型链指向是可以被修改的,而instanceof完全依赖原型链,所以检测出来的结果“仅供参考”
开发运用:
1.检测是否为某个类的实例
2.偶尔“不需要多么严谨”的数据类型检测,可以用它来处理一下,例如:细分对象
const arr = [1, 33];
// console.log(arr instanceof Array); // true
// console.log(arr instanceof Object); // true
// console.log(arr instanceof RegExp); // false
const throwErr = (value, dataType) => {
//检测右侧dataType是否是一个函数或者对象
if (typeof dataType !== 'function') {
throw new TypeError(`Right-hand side of 'instanceof' is not an object`);
}
// 原始值一律返回false 不处理
if (value === null || /^(object|function)$/.test(value)) {
return false;
}
// 不能存在原型对象
if (!dataType.hasOwnProperty('prototype')) {
throw new TypeError(
`Function has non-object prototype 'undefined' in instanceof check`
);
}
};
// 定义_instanceof实现 instanceof 检测原理
const _instanceof= (value, dataType) => {
// 错误处理
throwErr(value, dataType);
// 兼容es6浏览器版本 undefined 存在Symbol.hasInstance
if (typeof Symbol !== 'undefined') {
const hasInstance = dataType[Symbol.hasInstance];
if (hasInstance) return hasInstance.call(dataType, value);
}
// 不兼容es6版本浏览器
let selfProto = Object.getPrototypeOf(value);
while (selfProto) {
if (selfProto === dataType.prototype) return true;
selfProto = Object.getPrototypeOf(selfProto);
}
return false;
};
console.log(_instanceof(arr, Array), '手写'); // true
console.log(_instanceof(arr, Object), '手写'); // true
console.log(_instanceof(arr, RegExp), '手写'); // true
console.log(
_instanceof(arr, () => {}),
'手写'
); // Function has non-object prototype 'undefined' in instanceof check
检测方式三 、Object.prototype.toString.call
说明:除了Object之外,其他数据类型内置类的原型对象上,也存在tostring方法,只不过都是用来转化为字符串的,只要Object.protitype.toString是可以检测数据类型的,检测固定返回固定形式的"[object Object]"
基本语法:
Object.prototype.toString.call([value])
返回值:“[object Object]” => “[object ?]”
检测原始值,“?”这部分是自己所属的构造函数「null->Null undefined->Undefined」
检测的是对象,可以很精准的区分是哪一种对象(弥补了typeof无法细分对象的弊端)
“?”这部分是啥值:
首先查看[value]值是否具备Symbol.toStringTag这个属性,如果有,属性值是啥,最后“?”这部分就是啥;如果没有,一般是获取自己所属构造函数的名字!!
开发运用:
检测对象(而且是想细分对象),则基于toString这个办法
const toString = Object.prototype.toString;
let isNull = null,
num = 122,
str = '8nnn',
bl = true,
ud = undefined,
arr = [22, 'dd'],
fn = () => {},
fn1 = function Fn1() {},
obj = { ob: 'typeof obj' },
sym = Symbol('您好'),
bgin = 100n;
console.log(toString.call(isNull)); //[object Null]
console.log(toString.call(str)); //[object String]
console.log(toString.call(num)); //[object Boolean]
console.log(toString.call(bl)); //[object Undefined]
console.log(toString.call(ud)); //[object Boolean]
console.log(toString.call(arr)); //[object Array]
console.log(toString.call(fn)); //[object Function]
console.log(toString.call(new fn1())); //[object Object]
console.log(toString.call(obj)); //[object Object]
console.log(toString.call(sym)); //[object Symbol]
console.log(toString.call(bgin)); //[object BigInt]
console.log(toString.call(() => {})); //[object Function]
// 从检测结果来看 检测类型都比较精准 开发推荐使用该方式对引用类型进行细分
检测方式四 、constructor
基本语法 [value].constructor===[ctor]
检测一个值的构造函数是否是XXX,从而判断他的数据类型!
const arr = [1,22]
arr.constructor===Array 说明是数组类型
检测特点:
1.因为constructor很容易被修改,所以检测的结果“仅供参考”
2.可以处理原始值「默认“装箱”」
3.可以区分是否为“标准普通对象”