这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
前言
检测数据类型再开发中也是比较常用的, 其实想到检测数据类型可能大脑里面就是instanceof
、typeof
、Object.property.toString.call()
。 以上三种检测数据类型,今天就一块测试下具体有什么区别? 或者是不是还有什么其他的方法?
开始
开始测试
instanceof
instanceof
其实只能检测出引用数据类型:Array
、Object
、Function
......
代码测试:
//示例1(数字类型Number):
console.log( 123 instanceof Number, 'instanceof检测数字类型')
//输出:false "instanceof检测数字类型"。
//**结论: instanceof 不能用来检测数字类型**
//示例2(字符串String)
console.log('' instanceof String, 'instanceof检测字符串类型')
//输出:false "instanceof检测字符串类型"
//**结论:instanceof 不能用来检测字符串类型**
//示例3(布尔Boolean)
console.log(true instanceof Boolean, 'instanceof检测布尔类型')
// 输出: false "instanceof检测布尔类型"
//**结论: instanceof 不能用来检测布尔类型**
//示例4(null)
let a;
console.log(a instanceof null, 'instanceof检测Null类型')
//抛出错误:Uncaught TypeError: Right-hand side of 'instanceof' is not an object
//**结论: instanceof 不能用来检测null类型**
//示例5(undefined)
console.log(undefined instanceof undefined, 'instanceof检测undefined类型')
//抛出错误:VM120801:1 Uncaught TypeError: Right-hand side of 'instanceof' is not an object
//**结论:instanceof不能检测undefined类型**
//示例6(Function)
console.log((() => {}) instanceof Function, 'instanceof检测函数类型')
//输出: true "instanceof检测函数类型"
//**结论:instanceof能检测函数类型**
//示例7(Object)
console.log({} instanceof Object, 'instanceof检测Object类型')
//输出: true "instanceof检测Object类型"
//**结论:instanceof能检测Object类型**
//示例8(Array)
console.log([] instanceof Array, 'instanceof检测Array类型')
//输出: true "instanceof检测Array类型"
//**结论:instanceof能检测Array类型**
//示例8(Date)
console.log((new Date()) instanceof Date, 'instanceof检测Date类型')
//输出: true "instanceof检测Date类型"
//**结论:instanceof能检测Date类型**
// 示例9(new String())
console.log((new String(123)) instanceof String, 'instanceof检测通过new出来的String类型')
//输出: true "instanceof检测通过new出来的String类型"
//**结论:instanceof能检测通过new出来的String类型**
示例9的输出截图:
大家有兴趣可以去研究下 String
和 new String()
的区别,求其实是没用到这个new String()
结论:
instanceof
能对Array
、Object
、Function
、Date
等进行检测,其他(引用类型)都不支持;
instanceof 原理
以
[] instanceof Array
为例,instanceof
的工作原理就是调用[]
的每一层__proto__
隐士原型 与Array
的prototype
显示原型 做对比
代码实现示例:
function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
const O = R.prototype; // 取 R 的显示原型
L = L.__proto__; // 取 L 的隐式原型
while (true) {
if (L === null) {
return false;
}
if (O === L) {
return true;
}
L = L.__proto__;
}
}
//测试一下:
console.log(instance_of([], Array), '数组类型检测')
console.log(instance_of({}, Object), '对象类型检测')
console.log(instance_of(()=>{}, Function), '函数类型检测')
/**
* true "数组类型检测"
* true "对象类型检测"
* true "函数类型检测"
*/
typeof
typeof
支持检测基本类型:Number
、String
、Undefined
、Boolean
, 支持检测引用类型;Function
, 无法检测Object
、Array
、Date
、Null
代码测试:
//示例1:typeof 检测数字类型
console.log(typeof(123) === 'number')
//输出:true
//结论:typeof支持检测数字类型
//示例2: typeof 检测字符串类型
console.log(typeof('') === 'string')
//输出:true
//结论:typeof支持检测字符串类型
//示例3: typeof 检测布尔类型
console.log(typeof(true) === 'boolean')
//输出:true
//结论:typeof支持检测布尔类型
//示例4: typeof 检测null类型
console.log(typeof(null) === 'null')
//输出:false , 打印出来是:"object"
//结论:typeof支持检测null类型
//示例5: typeof 检测undefined类型
console.log(typeof(undefined) === 'undefined')
//输出:true
//结论:typeof支持检测undefined类型
//示例6: typeof 检测数组类型
console.log(typeof([]) === 'array')
//输出:false, 打印:"object"
//结论:typeof不支持检测数组类型
//示例7: typeof 检测对象类型
console.log(typeof({}) === 'object')
//输出:true, 虽然是true,但是它检测数组也是object,所以用来检测对象是不太准确的
//结论:typeof不支持检测对象类型
//示例8: typeof 检测函数
console.log(typeof(() => {}) === 'function')
//输出:true
//结论:typeof支持检测对象类型
结论:
typeof
支持检测(Number, String, Boolean, Undefined, Function
)
typeof原理
typeof原理:不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位存储其类型信息。
// 000: 对象
// 010: 浮点数
// 100:字符串
// 110:布尔
// 1:整数
typeof null 为"object", 原因是因为 不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位都为0的话会被判断为Object类型,null的二进制表示全为0,自然前三位也是0,所以执行typeof时会返回"object"。一个不恰当的例子,假设所有的Javascript对象都是16位的,也就是有16个0或1组成的序列,猜想如下:
Array: 1000100010001000
null: 0000000000000000
typeof [] // "object"
typeof null // "object"
因为Array和null的前三位都是000。为什么Array的前三位不是100?因为二进制中的“前”一般代表低位, 比如二进制00000011对应十进制数是3,它的前三位是011
Object.property.toString.call()
Object.property.toString.call()
能检测所有的数据类型 代码测试
let Type = {}
const type = ['String', 'Array', 'Number', 'Function', 'Boolean', 'Object', 'Undefined', 'Null']
for( let i = 0; i < type.length; i++) {
(function(type){
Type[`is${type}`] = function(obj) {
return Object.prototype.toString.call(obj) === `[object ${type}]`
}
})(type[i])
}
console.log(Type.isArray([]), '数组类型检测')
console.log(Type.isString(''), '字符串类型检测')
console.log(Type.isNumber(123), '数值类型检测')
console.log(Type.isFunction(() => {}),'函数类型检测')
console.log(Type.isBoolean(true), '布尔类型检测')
console.log(Type.isObject({}) , '对象类型检测')
console.log(Type.isUndefined(undefined) , 'undefined类型检测')
console.log(Type.isNull(null) , 'null类型检测')
/**
* 输出:
*
* true "数组类型检测"
* true "字符串类型检测"
* true "数值类型检测"
* true "函数类型检测"
* true "布尔类型检测"
* true "对象类型检测"
* true "undefined类型检测"
* true "null类型检测"
* **/
其他
Array.isArray()
Array.isArray()
可以用来检测是否是数组
用法示例:
console.log(Array.isArray([]), '检测是否是数组') //输出: true "检测是否是数组"
Array.isArray 原理
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
//对 就上面的Object.prototype.toString.call()
isNaN()
isNaN()
用来判断是否是数字类型? 是数字返回false
, 不是数字返回true
。
- 1、
'123'
这种类型纯数字的字符串也会返回false
, - 2、
''
空字符串也会返回false
- 3、
null
也会返回false
- 4、布尔类型也会返回
false
用法示例:
console.log(isNaN(123), '用来检测是否是数字类型')
//输出:false "用来检测是否是数字类型"
console.log(isNaN(''), '用来检测是否是数字类型')
//输出:false "用来检测是否是数字类型"
console.log(isNaN(null), '用来检测是否是数字类型')
//输出:false "用来检测是否是数字类型"
console.log(isNaN(true), '用来检测是否是数字类型')
//输出:false "用来检测是否是数字类型"
isNaN 原理解析
isNaN函数接受一个参数,原理是先尝试将参数转换为数值型,调用的是Number()方法,再进行判断
//1. 数值:自然转为数值
//2. 字符串
Number('123') // 123
Number('123abc') // NaN
Number(' ') // 0
// 3. 布尔值
Number(true) // 1
Number(false) // 0
// 4. undefined
Number(undefined) // NaN
//5. null
Number(null) // 0
总结:根据isNaN()方法返回的是true还是false可以检测参数是否可以像number那样是可运算的,如果是不可运算的,则可赋予这个参数一个默认的值或者是其他合适的内容,就可以得到一个隐式转换参数数值的函数。我一直以为是判断是否是数值类型.......
constructor
利用
constructor
进行类型检测, 缺点:一个数据的constructor
是可以被更改的, 且基本数据类型没有constructor
无法检测
代码示例:
console.log([].constructor === Array, 'constructor检测数据类型')
//输出: true "constructor检测数据类型"
console.log({}.constructor === Object, 'constructor检测数据类型')
//输出: true "constructor检测数据类型"
console.log((() => {}).constructor === Function, 'constructor检测数据类型')
//输出: true "constructor检测数据类型"
总结
检测数据类型大致就以上几种instanceof
、typeof
、Object.property.toString.call()、Array.isArray()、constructor、isNaN()
,大家如果还有其他方式校验数据类型,记得评论分享吖
参考链接
结束语
- 大家好 我是三原,多谢您的观看,我会更加努力(๑•̀ㅂ•́)و✧多多总结。
- 每个方法都是敲出来验证过通过的,有需要可以放心复制。
- 如果您给帮点个赞👍就更好了 谢谢您~~~~~
- 期待您的关注