第173天:面向对象——数据类型检测的四种方法

简介: 一、typeof1 console.log(typeof 12); // number2 var str = 'iceman';3 console.log(typeof str); // string使用typeof检测数据类型,首先返回的都是一个字符串,其次字符串中包含了对应的数据类型...

一、typeof

1 console.log(typeof 12); // number
2 var str = 'iceman';
3 console.log(typeof str); // string

使用typeof检测数据类型,首先返回的都是一个字符串,其次字符串中包含了对应的数据类型,例如:"number"、"string"、"boolean"、"undefined"、"function"、"object"

面试题:

1 console.log(typeof typeof typeof function () {}); // string

typeof的局限性:不能具体的细分是数组还是正则,还是对象中其他的值,因为使用typeof检测数据类型,对于对象数据类型中的所有的值,最后返回的结果都是"object"。

应用一:添加默认值

 1 function fn(num1, num2) {
 2     // 方式一
 3     // if (typeof num2 === 'undefined') {
 4     //   num2 = 0;
 5     // }
 6 
 7     // 方式二:不适用fn(10,false)这种情况
 8     num2 = num2 || 0;
 9 }
10 fn(10);

应用二:回调函数调用

1 function fn(callback) {
2     //typeof callback === 'function' ? callback() : null;
3     callback && callback();
4 }
5 fn(function () {
6     
7 });

二、instanceof

1 var ary = [];
2 console.log(ary instanceof Array); // true
3 console.log(ary instanceof Object); // true
4 
5 function fn() {}
6 console.log(fn instanceof Function); // true
7 console.log(fn instanceof Object); // true

只要在当前实例的原型链上,用instanceof检测出来的结果都是true,所以在类的原型继承中,最后检测出来的结果未必是正确的,例如:

1 function Fn() {
2 }
3 Fn.prototype = new Array; // 原型继承:让子类的原型等于父类的一个实例
4 var f = new Fn;
5 console.log(f instanceof Array); // true

三、constructor

constructor即构造函数,作用和instanceof非常的相似。

1 var obj = [];
2 console.log(obj.constructor === Array); // true
3 console.log(obj.constructor === RegExp); // false

constructor可以处理基本数据类型的检测

1 var num = 1;
2 console.log(num.constructor === Number); // true

constructor检测Object和instanceof不一样,一般情况下是检测不了的

1 var reg = /^$/;
2 console.log(reg.constructor === RegExp); // true
3 console.log(reg.constructor === Object); // false

constructor的局限性:我们可以把类的原型进行重写,在重写的过程中,很有可能把之前的constructor给覆盖了,这样检测出来的结果就是不准确的。

1 function Fn() {
2 }
3 Fn.prototype = new Array;
4 var f = new Fn;
5 console.log(f.constructor); // Array

对于特殊的数据类型nullundefined,它们的所属类型是NullUndefined,但是浏览器把这两个类保护起来了,不允许在外面访问使用。

四、Object.prototype.toString.call()

toString的理解:

  • 咋一看应该是转换为字符串,但是某些toString方法不仅仅是转换为字符串。对于Number、String、Boolean、Array、RegExp、Date、Function原型上的toString方法都是把当前的数据类转换为字符串的类型(它们的作用仅仅是用来转换为字符串的)

  • Object.prototype.toString并不是用来转换为字符串的。



1 ({name:"iceman"}).toString() // --> "[object Object]"
2  Math.toString() // --> "[object Math]"

Number.prototype.toString是转换字符串的

1 console.log((1).toString()); // --> Number.prototype.toString,--> "1"  转换为字符串
2 console.log((1).__proto__.__proto__.toString()); // Object.prototype.toString --> "[object Object]"
3 console.log((128).toString(2/8/10)); // 把数字转换为二进制/八进制/十进制

Object.prototype.toStrong.call()是检测数据类型最准确最常用的方式,其原理为:

  • 先获取Object原型上的toString方法,让方法执行,并且改变方法中的this关键字的指向;

  • Object.prototype.toString 它的作用是返回当前方法的执行主体(方法中this)所属类的详细信息;


1 var obj = {name:'iceman'};
2 // toString中的this是obj,返回的是obj所属类的信息 --> "[object Object]"
3 // 第一个object代表当前实例是对象数据类型的(这个是固定死的)
4 // 第二个Object,代表的是obj所属的类是Object
5 console.log(obj.toString());
6 
7 // toString中的this是Math,那么返回的是Math所属类的信息 --> "[object Math]"
8 console.log(Math.toString());

检测其他类型:

 1 var ary = [];
 2 console.log(Object.prototype.toString.call(ary)); // --> "[object Array]"
 3 console.log(Object.prototype.toString.call(/^$/)); // --> "[object RegExp]"
 4 console.log(({}).toString.call(1)); // --> "[object Number]"
 5 
 6 console.log(({}).toString.call('珠峰')); // --> "[object String]"
 7 console.log(({}).toString.call(true)); // --> [object Boolean]
 8 console.log(({}).toString.call(undefined)); // -->[object Undefined]
 9 console.log(({}).toString.call(null)); // -->[object Null]
10 console.log(({}).toString.call(function () {})); // -->[object Function]

实际使用:

1 var ary = [];
2 console.log(Object.prototype.toString.call(ary) === '[object Array]'); // true
3 
4 var reg = /^\[object Array\]$/;
5 console.log(reg.test(Object.prototype.toString.call(ary))); // true

检测原型继承的情况:

1 function Fn() {
2 }
3 Fn.prototype = new Array;
4 var f = new Fn;
5 console.log(f instanceof Array); // true
6 console.log(Object.prototype.toString.call(f) === '[object Array]'); // false

 

相关文章
|
消息中间件 存储 Kubernetes
kafka/pulsar on k8s
kafka/pulsar on k8s
kafka/pulsar on k8s
|
安全 网络协议 网络安全
UDP Flood是什么?及其防护方法
UDP Flood是互联网上最经典的DDoS(Distributed Denial of Service)攻击之一。攻击者在短时间内向目标设备发送大量的UDP报文,导致链路拥塞甚至网络瘫痪。一般的UDP报文由攻击工具伪造,通常在数据段具备相同的特征,另一部分由真实网络设备发出的UDP报文,虽然数据段不相同,但固定的目的端口也可作为一种特征。 确定UDP攻击报文的特征后,即可根据特征进行过滤。特征过滤就是常说的指纹过滤,可根据攻击报文的特征,自定义过滤属性。指纹过滤包括静态指纹过滤和动态指纹学习两种方法。
UDP Flood是什么?及其防护方法
|
存储 监控 数据可视化
日志分析对决:揭示 ELK 与 GrayLog 的优势和差异
日志分析对决:揭示 ELK 与 GrayLog 的优势和差异
3432 0
ly~
|
存储 安全 网络安全
云数据库的安全性如何保障?
云数据库的安全性可通过多种方式保障,包括多因素身份验证、基于角色的访问控制及最小权限原则,确保仅有授权用户能访问所需数据;采用SSL/TLS加密传输和存储数据,加强密钥管理,防止数据泄露;定期备份数据并进行异地存储与恢复演练,确保数据完整性;通过审计日志、实时监控及安全分析,及时发现并应对潜在威胁;利用防火墙、入侵检测系统和VPN保护网络安全;选择信誉良好的云服务提供商,确保数据隔离及定期安全更新。
ly~
904 2
|
安全 关系型数据库 Linux
高危漏洞CVE-2024-38077的修复指南
根据2024年8月9日,国家信息安全漏洞共享平台(CNVD)收录了Windows远程桌面许可服务远程代码执行漏洞(CNVD-2024-34918,对应CVE-2024-38077)。未经身份认证的攻击者可利用漏洞远程执行代码,获取服务器控制权限。目前,该漏洞的部分技术原理和概念验证伪代码已公开,厂商已发布安全更新完成修复。CNVD建议受影响的单位和用户安全即刻升级到最新版本。
|
消息中间件
【RabbitMQ七】——RabbitMQ发布确认模式(Publisher Confirms)
【RabbitMQ七】——RabbitMQ发布确认模式(Publisher Confirms)
821 0
|
安全 Java Spring
springboot2.1.0漏洞修复及踩坑
springboot2.1.0漏洞修复及踩坑
552 0
|
存储 算法 C++
括号序列:使用C++检查括号有效性
括号序列:使用C++检查括号有效性
323 0
|
缓存 网络协议 数据挖掘
如何使用弱网环境来验证游戏中的一些延迟问题
如何使用弱网环境来验证游戏中的一些延迟问题
|
存储 安全 编译器
C/C++面试题:堆栈的作用
C/C++面试题:堆栈的作用
195 0