js判断数据类型的方法有哪些?有什么不同

记录第一次面试——广州凡科(三)

第三题:热身的js题
到了js部分就要格外注意表达问题了。毕竟对面的面试官听不懂你的表达,基本就让面试的气氛十分尴尬。凉了一半
所以记住一些表达句子很有必要。

1.typeof
2.instanceof
3.constructor
4.Object.prototype.toString()

首先回顾:js的数据类型
基本分为基本类型和引用类型
基本类型:布尔、Number、String、Undefined、Null、Symbol
引用类型:Object、Array、Data、RegExp、Function、基本包装类型(Boolean、Number、String)单体内置对象(Global、Math)

  • typeof

用法&例子:(真是不想说笔试的时候忘记怎么用typeof了)
返回数据类型的字符串形式

1  typeof "";  //"string"
2  typeof 1;   //"number"
3  typeof false; //"boolean"
4  typeof undefined; //"undefined"
5  typeof function(){}; //"function"
6  typeof {}; //"object"
7  typeof Symbol(); //"symbol"
8  typeof null; //"object"
9  typeof []; //"object"
10  typeof new Date(); //"object"
11  typeof new RegExp(); //"object"
12  typeof new Number(33) //"object"
13  typeof Null //"undefined"

总结:
1.可以对基本类型做出准确的判断(除了null)可以返回的数据类型有:Number、String、Undefined、Symbol、Object、Function

2.从第8条看出,null返回的是“object”,因为null被认为是一个空的对象引用,而Null或者N返回的是“undefined”,就是找不到数据类型嘛

3.对于引用类型,typeof返回的是object,因为所有对象的原型链最终指向Object,Object是所有对象的祖宗

4.从第12条看出,使用new 字符初始化的对象,typeof都是返回object

5.从第13条看出,对于未声明变量Null,typeof会返回“undefined”

6.最后一点则是我迷惑了很久的大小写的问题。
我们写出有什么数据类型是大写的,但是typeof返回的是小写的字符串形式。所以typeof 1===Number是返回false的。但是当我们使用instanceof 时,

var a= new Number(22);
a instanceof Number // true
a instanceof number // 报错!number is not defined
  • instanceof

instanceof判断A是否是B的实例,表达式为:A instanceof B,如果是返回true,否则返回false。在原型链上的原型都可以返回true的
比如:

[] instanceof Array; // true
[] instanceof Object; // true

所以instanceof只能判断两个对象是否属于实例关系,不能具体判断一个对象实例属于哪种类型
undefined、null用instanceof 会报错

  • constructor

当一个函数 F被定义时,JS引擎会为F添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向自身。

function F(){}
F.prototype
constructor: ƒ F()
__proto__: Object

当执行 var f = new F() 时,F 被当成了构造函数,f 是F的实例对象,此时原型上的 constructor 就被遗传到了新创建的对象上,因此 f.constructor == F

var f=new F()
f.constructor===F // true

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

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

F.prototype={a:"XXXX"}
var ff=new F()
ff.constructor===F  // false
ff.constructor  // ƒ Object() { [native code] }

*为什么变成了 Object?
因为 prototype 被重新赋值的是一个 { }, { } 是 new Object() 的字面量,因此 new Object() 会将 Object 原型上的 constructor 传递给 { },也就是 Object 本身。

因此重写原型一般需要给constructor重新赋值ff.constructor=F

  • Object.prototype.toString()

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

Object.prototype.toString.call("a")
"[object String]"
Object.prototype.toString.call(undefined)
"[object Undefined]"
Object.prototype.toString.call(null)
"[object Null]"
Object.prototype.toString.call(new Date())
"[object Date]"

推荐阅读更多精彩内容