You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
可以看到前三个都是以对象字面量创建的基本数据类型,但是却不是所属类的实例,这个就有点怪了。后面三个是引用数据类型,可以得到正确的结果。如果我们通过 new 关键字去创建基本数据类型,你会发现,这时就会输出 true,如下:
具体为什么会这样呢?我们看 MDN 的解释:
varsimpleStr="This is a simple string";varnewStr=newString("String created with constructor");simpleStrinstanceofString;// 返回 false, 非对象实例,因此返回 falsenewStrinstanceofString;// 返回 true
本系列的主题是 JavaScript 深入系列,每期讲解一个技术要点。如果你还不了解各系列内容,文末点击查看全部文章,点我跳转到文末。
如果觉得本系列不错,欢迎 Star,你的支持是我创作分享的最大动力。
一文搞定 JavaScript 的数据类型检测
1. typeof
对于原始数据类型,我们可以使用 typeof 操作符来判断他的数据类型:
看看控制台输出什么
可以看到,typeof 对于基本数据类型判断是没有问题的,但是遇到引用数据类型(如:Array)是不起作用的。
typeof null
在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"。
曾有一个 ECMAScript 的修复提案(通过选择性加入的方式),但被拒绝了。该提案会导致 typeof null === 'null'。
2. instanceof
typeof 操作符对于原始类型的判断还差强人意,但他是没法用来区分引用数据类型的,因为所有的引用数据类型都会返回"object"。于是 JavaScript 引入了 Java 中使用的 instanceof,用来判断一个变量是否是某个对象的实例,所以对于引用类型我们使用 instanceof 来进行类型判断。
instanceof
运算符用于检测构造函数的prototype
属性是否出现在某个实例对象的原型链上。用法:
object instanceof constructor
instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。
暂且不考虑 null 和 undefined(这两个比较特殊),看看控制台输出什么。
可以看到前三个都是以对象字面量创建的基本数据类型,但是却不是所属类的实例,这个就有点怪了。后面三个是引用数据类型,可以得到正确的结果。如果我们通过 new 关键字去创建基本数据类型,你会发现,这时就会输出 true,如下:
具体为什么会这样呢?我们看 MDN 的解释:
接下再来说说为什么 null 和 undefined 为什么比较特殊,实际上按理来说,null 的所属类就是 Null,undefined 就是 Undefined,但事实并非如此:控制台输出如下结果:
浏览器压根不认识这两货,直接报错。在第一个例子你可能已经发现了,typeof null 的结果是 object,typeof undefined 的结果是 undefined
尤其是 null,其实这是 js 设计的一个败笔,早期准备更改 null 的类型为 null,由于当时已经有大量网站使用了 null,如果更改,将导致很多网站的逻辑出现漏洞问题,就没有更改过来,于是一直遗留到现在。具体为什么
typeof null = ‘object’
,我们前文已经介绍过了,作为学习者,我们只需要记住就好。3. constructor
constructor 属性返回 Object 的构造函数。
就是返回对象相对应的构造函数。从定义上来说跟 instanceof 不太一致,但效果都是一样的。
如:
(a instanceof Array)
// a 是否 Array 的实例?true or false(a.constructor == Array)
// a 实例的构造函数是否为 Array? true or false(这里依然抛开 null 和 undefined)乍一看,constructor 似乎完全可以应对基本数据类型和引用数据类型,都能检测出数据类型,事实上并不是如此,来看看为什么:
我声明了一个构造函数,并且把他的原型指向了 Array 的原型,所以这种情况下,constructor 也显得力不从心了。
看到这里,是不是觉得绝望了。没关系,终极解决办法就是第四种办法,看过 jQuery 源码的人都知道,jQuery 实际上就是采用这个方法进行数据类型检测的。
4. Object.prototype.toString.call()
可以看到,所有的数据类型,这个办法都可以判断出来。那就有人质疑了,假如我把他的原型改动一下呢?如你所愿,我们看一下:
可以看到,依然可以得到正确的结果。
总结
参考
查看全部文章
博文系列目录
交流
各系列文章汇总:https://github.com/yuanyuanbyte/Blog
我是圆圆,一名深耕于前端开发的攻城狮。
The text was updated successfully, but these errors were encountered: