Js进阶23-判断数据类型的几种方法

首先简单的说一下 js 中的几种数据类型。

js 数据类型分为基本数据类型引用数据类型

基本数据类型:string、number、boolean、null、undefined;

引用数据类型:Object、Array、Date、Function、Error、RegExp、Math、Globle。

判断数据类型的方法一般可以通过:typeof、instanceof、constructor 和 toString 四种常用方法。

一、typeof

typeof 可以对基本数据类型做出准确的判断,但对于引用数据类型,使用它还不够。 

typeof 可以对基本数据类型做出准确的判断(除了 null,typeof null 返回 'object'),而对于引用数据类型返回的基本上都是 ‘object’。其实返回 ‘object’ 也没有错,因为所有对象的原型链最终都指向了 Object,Object 是所有对象的“祖宗”。 但当我们需要知道某个对象的具体类型时,typeof 就显得有些力不从心了。 

关于 typeof 的详细内容请见 Js进阶10-typeof 的返回值

二、instanceof

instanceof 判断对象和构造函数在原型链上是否有关系,如果有关系,返回 true,否则返回 false。

function Aaa() {}
var a1 = new Aaa();
alert(a1 instanceof Aaa); // true---判断 a1 和 Aaa 是否在同一个原型链上,是的话返回真,否则返回假
var arr = [];
alert(arr instanceof Aaa); // false

instanceof 多种情况:

var str = 'hello';
console.log(str instanceof String); // false
var bool = true;
console.log(bool instanceof Boolean); // false
var num = 123;
console.log(num instanceof Number); // false
var nul = null;
console.log(nul instanceof Object); // false
var und = undefined;
console.log(und instanceof Object); // false
var oDate = new Date();
console.log(oDate instanceof Date); // true
var json = {};
console.log(json instanceof Object); // true
var arr = [];
console.log(arr instanceof Array); // true
var reg = /a/;
console.log(reg instanceof RegExp); // true
var fun = function(){};
console.log(fun instanceof Function); // true
var error = new Error();
console.log(error instanceof Error); // true

从上面的运行结果可以看到,基本数据类型是没有检测出他们的类型,但是我们使用下面的方式创建 num、string、boolean,是可以检测出类型的:

var num = new Number(123);
var str = new String('abcdef');
var boolean = new Boolean(true);
console.log(num instanceof Number); // true
console.log(str instanceof String); // true
console.log(boolean instanceof Boolean); // true

三、constructor

constructor 查看对象对应的构造函数。

constructor 在其对应对象的原型下面,是自动生成的。当我们写一个构造函数的时候,程序会自动添加:构造函数名.prototype.constructor = 构造函数名。

function Aaa() {}
// Aaa.prototype.constructor = Aaa; // 每一个函数都会有的,都是自动生成的
console.log(Aaa.prototype.constructor === Aaa); // true

判断数据类型的方法:

var str = 'hello';
console.log(str.constructor === String); // true
var bool = true;
console.log(bool.constructor === Boolean); // true
var num = 123;
console.log(num.constructor === Number); // true
// var nul = null;
// console.log(nul.constructor === Object); // 报错
// var und = undefined;
// console.log(und.constructor === Object); // 报错
var oDate = new Date();
console.log(oDate.constructor === Date); // true
var json = {};
console.log(json.constructor === Object); // true
var arr = [];
console.log(arr.constructor === Array); // true
var reg = /a/;
console.log(reg.constructor === RegExp); // true
var fun = function(){};
console.log(fun.constructor === Function); // true
var error = new Error();
console.log(error.constructor === Error); // true

从上面的测试中可以看到,undefined 和 null是不能够判断出类型的,并且会报错。因为 undefined 和 null是无效的对象,因此是不会有 constructor。

同时注意到的是:使用 constructor 是不保险的,因为 constructor 属性是可以被修改的,会导致检测出的结果不正确。

function Aaa() {}
Aaa.prototype.constructor = Aaa; // 程序可以自动添加,当我们写个构造函数的时候,程序会自动添加这句代码
function BBB() {}
Aaa.prototype.constructor = BBB; // 此时我们就修改了Aaa构造函数的指向问题
alert(Aaa.construtor == Aaa); // false

可以看出,constructor 并没有正确检测出正确的构造函数。

四、Object.prototype.toString.call(obj)

Object.prototype.toString.call,可以说不管是什么类型,它都可以立即判断出来。

toString 是 Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是 toString 运行时 this 指向的对象类型,返回的类型。

格式为[object xxx],xxx 是具体的数据类型,其中包括:

String、Number、Boolean、Undefined、Null、Function、Date、Array、RegExp、Error、HTMLDocument......

基本上所有变量的类型都可以通过这个方法获取到。 

var str = 'hello';
console.log(Object.prototype.toString.call(str)); // [object String]
var bool = true;
console.log(Object.prototype.toString.call(bool)); // [object Boolean]
var num = 123;
console.log(Object.prototype.toString.call(num)); // [object Number]
var nul = null;
console.log(Object.prototype.toString.call(nul)); // [object Null]
var und = undefined;
console.log(Object.prototype.toString.call(und)); // [object Undefined]
var oDate = new Date();
console.log(Object.prototype.toString.call(oDate)); // [object Date]
var json = {};
console.log(Object.prototype.toString.call(json)); // [object Object]
var arr = [];
console.log(Object.prototype.toString.call(arr)); // [object Array]
var reg = /a/;
console.log(Object.prototype.toString.call(reg)); // [object RegExp]
var fun = function(){};
console.log(Object.prototype.toString.call(fun)); // [object Function]
var error = new Error();
console.log(Object.prototype.toString.call(error)); // [object Error]

从这个结果也可以看出,不管是什么类型,Object.prototype.toString.call 都可以判断出其具体的类型。

五、四种方法的优缺点

比较typeofinstanceofconstructorObject.prototype.toString.call
优点使用简单能检测出引用类型基本能检测所有的类型(除了null和undefined)检测出所有的类型
缺点只能检测出基本类型(除了null)不能检测出基本类型,且不能跨 iframeconstructor 易被修改,也不能跨 iframeIE6 下,undefined 和 null 均为Object

从上表中看到了,instanceof 和 constructor 不能跨 iframe,看下面的例子:

// 跨页面判断是否为数组
window.onload = function(){
  var oF = document.createElement('iframe');
  document.body.appendChild( oF );
  var ifArray = window.frames[0].Array;
  var arr = new ifArray();
  console.log(arr.constructor === Array);  //false
  console.log(arr instanceof Array);  //false
  console.log(Object.prototype.toString.call(arr) === '[object Array]');  //true
};

从结果中可以看出,constructor 和 instanceof 都没有正确的判断出类型,只有 Object.prototype.toString.call 正确判断出来了。

如果让说一种最简单的判断是数组的方法,就是 Object.prototype.toString.call!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晴雪月乔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值