js检测数据类型的四种办法


最近经常听到前端朋友在面试时,会被问到 js 检测数据类型的四种办法,为此我来总结一下,温故而知新。

js 检测数据类型的四种办法

  1. typeof

  2. instanceof

  3. constructor

  4. Object.prototype.toString.call()

下面我来依次说明

先举几个例子:

var a = "字符串";
var b = 222;
var c = [1, 2, 3];
var d = new Date();
var e = function () {
  alert("函数");
};
var f = function () {
  this.name = "22";
};
var g = null;
var h = undefined;
var i = true;
var j = {};

1.typeof

typeof:返回一个字符串,typeof 也是最常见的判断方法

alert(typeof a)  ------------> string
alert(typeof b)  ------------> number
alert(typeof c)  ------------> object
alert(typeof d)  ------------> object
alert(typeof e)  ------------> function
alert(typeof f)  ------------> function
alert(typeof g)  ------------> object
alert(typeof h)  ------------> undefined
alert(typeof i)  ------------> boolean
alert(typeof j)  ------------> object

从上面可以看出,typeof 对 Array,null 是不起作用的, typeof null 返回类型错误,返回 object,typeof Array 返回 object。

引用类型,除了 function 返回 function 类型外,其他均返回 object。

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

2.instanceof

instanceof:用于判断一个变量是否为某个类的实例.利用 instanceof 来判断 A 是否为 B 的实例,表达为 A instanceof B,返回一个布尔值。instanceof 的原理是通过检测对象的原型链上是否含有类型的原型。

还是以上面的例子来判断,暂且不考虑 null 和 undefined(这两个比较特殊),看看控制台输出什么

console.log(a instanceof String); //false
console.log(b instanceof Number); //false
console.log(i instanceof Boolean); //false
console.log(c instanceof Array); //true
console.log(d instanceof Object); //true
console.log(e instanceof Function); //true
console.log(f instanceof Function); //true

可以看到前三个都是以对象字面量创建的基本数据类型,但是却不是所属类的实例,这个就有点怪了。后面四个是引用数据类型,可以得到正确的结果。如果我们通过 new 关键字去创建基本数据类型,你会发现,这时就会输出 true,如下:

console.log(new String(a) instanceof String); //true
console.log(new Number(b) instanceof Number); //true
console.log(new Boolean(i) instanceof Boolean); //true

接下再来说说为什么 null 和 undefined 为什么比较特殊,实际上按理来说,null 的所属类就是 Null,undefined 就是 Undefined,但事实并非如此,由于浏览器压根不认识这 null 和 undefined,直接报错。在第一个例子你可能已经发现了,typeof null 的结果是 object,typeof undefined 的结果是 undefined

注意:尤其是 null,其实这是 js 设计的一个败笔,早期准备更改 null 的类型为 null,由于当时已经有大量网站使用了 null,如果更改,将导致很多网站的逻辑出现漏洞问题,就没有更改过来,于是一直遗留到现在。作为学习者,我们只需要记住就好。

3.constructor

constructor 是原型 prototype 的一个属性,当函数被定义时候,js 引擎会为函数添加原型 prototype,并且这个 prototype 中 constructor 属性指向函数引用, 因此重写 prototype 会丢失原来的 constructor。

console.log(a.constructor === String); //true
console.log(b.constructor === Number); //true
console.log(i.constructor === Boolean); //true
//console.log((null).constructor === Null)
//console.log((undefined).constructor === Undefined)
console.log(c.constructor === Array); //true
console.log(e.constructor === Function); //true
console.log(g.constructor === Object); //true

注意:

1:null 和 undefined 无 constructor,这种方法判断不了。

2:还有,如果自定义对象,开发者重写 prototype 之后,原有的 constructor 会丢失,因此,为了规范开发,在重写对象原型时一般都需要重新给 constructor 赋值,以保证对象实例的类型不被篡改。

4.Object.prototype.toString.call()

toString()方法是 Object 原型上的方法,调用此方法,返回格式为[object,xxx],xxx 即为判断的结果。对于 Object 对象可以直接调用 Object.prototype.toString(),对于其他数据类型,需要通过.call()来调用。

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 的引用

文章作者: BiLiang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 BiLiang !
评论
  目录