基本类型:String、Number、Boolean、Symbol、Undefined、Null

引用类型:Object (引用类型除 Object 外,还包括 Function 、Array、RegExp、Date 等等。)

鉴于 ECMAScript 是松散类型的,因此需要有一种手段来检测给定变量的数据类型。对于这个问题,JavaScript 也提供了多种方法,但遗憾的是,不同的方法得到的结果参差不齐。

1、typeof

typeof 是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。返回的结果用该类型的字符串(全小写字母)形式表示,包括以下 7 种:number、boolean、symbol、string、object、undefined、function 等。

typeof ''; // string 有效
typeof 1; // number 有效
typeof Symbol(); // symbol 有效
typeof true; //boolean 有效
typeof undefined; //undefined 有效
typeof null; //object 无效
typeof [] ; //object 无效
typeof new Function(); // function 有效
typeof new Date(); //object 无效
typeof new RegExp(); //object 无效

有些时候,typeof 操作符会返回一些令人迷惑但技术上却正确的值:

  • 对于基本类型,除 null 以外,均可以返回正确的结果。
  • 对于引用类型,除 function 以外,一律返回 object 类型。
  • 对于 null ,返回 object 类型。
  • 对于 function 返回  function 类型。

其中,null 有属于自己的数据类型 Null , 引用类型中的 数组、日期、正则 也都有属于自己的具体类型,而 typeof 对于这些类型的处理,只返回了处于其原型链最顶端的 Object 类型,没有错,但不是我们想要的结果。

2、instanceof

instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。 在这里需要特别注意的是:instanceof 检测的是原型,我们用一段伪代码来模拟其内部执行过程:

[] instanceof Array; // true
{} instanceof Object;// true
new Date() instanceof Date;// truefunction Person(){};
new Person() instanceof Person;[] instanceof Object; // true
new Date() instanceof Object;// true
new Person instanceof Object;// true

我们发现,虽然 instanceof 能够判断出 [ ] 是Array的实例,但它认为 [ ] 也是Object的实例,为什么呢?

我们来分析一下 [ ]、Array、Object 三者之间的关系:

从 instanceof 能够判断出 [ ].__proto__  指向 Array.prototype,而 Array.prototype.__proto__ 又指向了Object.prototype,最终 Object.prototype.__proto__ 指向了null,标志着原型链的结束。因此,[]、Array、Object 就在内部形成了一条原型链

从原型链可以看出,[] 的 __proto__  直接指向Array.prototype,间接指向 Object.prototype,所以按照 instanceof 的判断规则,[] 就是Object的实例。依次类推,类似的 new Date()、new Person() 也会形成一条对应的原型链 。因此,instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。

3、constructor

当一个函数 F被定义时,JS引擎会为F添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向 F 的引用。如下所示:

细节问题:

1. null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。

2. 函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object

4、toString

toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。

对于 Object 对象,直接调用 toString()  就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

Object.prototype.toString.call('') ;   // [object String]
Object.prototype.toString.call(1) ;    // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window 是全局对象 global 的引用

JS类型判断的四种方法以及各自的注意点相关推荐

  1. js数组去重的四种方法

    四种算法来实现这个目的: Array.prototype.unique1 = function () {var n = []; //一个新的临时数组for (var i = 0; i < thi ...

  2. JS获取随机数的四种方法(转)

    原帖:https://www.jb51.net/article/82747.htm JS没有现成的函数,能够直接生成指定范围的随机数. 但是它有个函数:Math.random()  这个函数可以生成 ...

  3. Js声明数组的四种方法

    //第一种 var A=[12,78,78,78,89] console.log(A)//第二种 var B=new Array(); B[0]=12 B[1]=34 B[2]=56 console. ...

  4. JS生成 UUID的四种方法

    全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) . GUID是一种由算法生成的二进制长度 ...

  5. js 循环对象的四种方法

    1.for in let obj = {'name': 'cookie','age': 18 }for (let key in obj) {console.log(key); // name agec ...

  6. JS - 前端生成 UUID 四种方法

    全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) . GUID 是一种由算法生成的二进制长 ...

  7. js创建数组的四种方法【2021.11.13】

    参考书籍<JavaScript百炼成仙> 1.直接量定义数组: var arr = [1,2,3]; 2.采用构造函数的方法创建数组对象: var a =new Array(); 3.也是 ...

  8. js创建数组的四种方法、常用方法、属性

    数组创建 1)var arrayObj = new Array(); 2)var arrayObj2 = new Array(5);3)var arrayObj3 = new Array(1, 2,. ...

  9. js获取时间戳的四种方法

最新文章

  1. 自己写的哈希表以及解决哈希冲突
  2. BTC上轨受阻继续调整,主流币分化BCH强势上行
  3. 微众WeCross 跨链平台(13)开发示例
  4. 洛谷 - P3980 [NOI2008]志愿者招募(最小费用最大流+思维建边)
  5. java面试题之----get和post请求方法的区别
  6. 一些PHP性能优化汇总
  7. Python爬虫实战之(五)| 模拟登录wechat 1
  8. 详解 Java NIO
  9. NPM包管理器跟换国内镜像CNPM
  10. onvif学习笔记4:Windows环境使用gsoap生成onvif框架代码
  11. 如何弄ad装配图_[分享][BCW]上海西康路189弄——“世界最美购物中心”幕墙的诞生...
  12. JDK安装配置环境变量以及配置完成后出现java命令能用但javac命令不能用 (JAVA_HOME失效)
  13. 超简单的Matlab附加功能安装包的安装方法
  14. 分享一下苹果手机绕激活锁的体验
  15. 边境的悍匪—机器学习实战:第七章 集成学习和随机森林
  16. 幼麟棋牌技术分享系列:H5棋牌游戏加载速度优化
  17. #2:在颓宅的边缘开始试探——4
  18. 大数据破获网售假耐克案
  19. ImageDraw类详解:几何图形的绘制与文字的绘制
  20. 某些老司机直播APP这么受欢迎?作为Android程序员如何进军音视频?

热门文章

  1. 论文阅读笔记2——Evading Defenses to Transferable Adversarial Examples by Translation-Invariant Attacks
  2. 10采用区块链智能合约管理智能城市房地产交易的概念框架
  3. 这些最基本的摄影技巧nbsp;你真的…
  4. windows无法连接打印机共享打印机常见错误码与解决方案
  5. vivo是如何夺得国内智能手机市场份额第二名的?
  6. Bounding Box预测(Bounding box predictions)
  7. 一个适合初学者的C++推箱子小游戏
  8. 用 Python 爬取 500 条豆瓣影评,看看《蚁人2》是否有看点?
  9. 《姜子牙》的故事没有讲好
  10. C# 电脑上提示未知发布者