JS中的类型检测

判断js对象类型之Object.prototype.toString.call(obj)

这里我们使用Object原型上的toString函数,是因为防止需要检测类型的obj对象自己定义了toString方法,或者对其进行了修改。

这里做一下测试

Object.prototype.toString.call('aaa')
"[object String]"
Object.prototype.toString.call(11)
"[object Number]"
Object.prototype.toString.call(true)
"[object Boolean]"
Object.prototype.toString.call(undefined)
"[object Undefined]"
Object.prototype.toString.call(null)
"[object Null]"
Object.prototype.toString.call({})
"[object Object]"
Object.prototype.toString.call([])
"[object Array]"
Object.prototype.toString.call(function(){})
"[object Function]"   
Object.prototype.toString.call(new Date)
"[object Date]"
Object.prototype.toString.call(/abc?/ig)
"[object RegExp]"

typeof

使用typeof判定对象类型有局限性,我们从判定结果来看局限性:

typeof 'aa'
"string"
typeof 11
"number"
typeof undefined
"undefined"
typeof true
"boolean"
typeof null
"object"
typeof []
"object"
typeof {}
"object"
typeof new Date()
"object"
typeof /^\[object\s(.*)\]$/
"object"
typeof function(){}
"function"

可以看出来,对于我们的复杂对象,返回都是object,这是我们已经预想到的,但是为什么对于null也返回object呢,这里其实可以说是js检测对象的一个“bug”,JS类型值是存在32BIT单元里,32位有1-3位表示TYPE TAG,其它位表示真实值而表示object的标记位正好是低三位都是0。由于 null 代表的是空指针(大多数平台下值为0x00,Number(null)===0),所以。。。

此外,还有以下特殊情况:

typeof new String
"object"
typeof new Boolean(true)
"object"
typeof new Number(1)
"object"

这种情况就要说到 基本包装类型了,上面代码中的String、Boolean和Number是es提供的3个引用类型,每当读取一个基本类型值得时候,就创建一个string、boolean和number三种基本类型的基本包装类型的对象。以下面的例子为例:

var s="hello";
var s0 = s.substring(2);

这里我们定义了一个基本类型stirng,将其赋给了s,下一行调用了s的substring方法;我们知道,stirng是基本类型,基本类型不是对象,因而是不应该有方法的,但是这里不是我们想的那么简单:这里在后台完成了一系列的工作:当运行到第二行,访问到s时,访问过程处于一种读取模式,在读取模式访问字符串时,后台操作如下:

  • 1.创建String类型的一个实例;
  • 2.在实例上调用指定方法;
  • 3.销毁这个实例;
    这就是我们定义了基本类型string,但是看起来这个string可以有方法的原因;当然这个原理对于number和boolean基本类型也是一样的;

总结来说:引用类型与基本包装类型的主要区别在与对象的生存期

typeof new Number(1)
"object"
typeof Number(2)
"number"
typeof 2
"number"
2===Number(2)
true

上面的代码中,使用new创建的引用类型的实例在指向刘离开作用域后仍保持在内存中,而自动创建的基本包装类型的对象,则只存在于代码的执行瞬间,然后立即被销毁;

instanceof

从上面的内容可以看出:typeof对于复杂数据类型显得无能为力;
object instanceof constructor
instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
typeof对于检测基本数据类型可以胜任,而instanceof从上述描述来看,由于包装类型的原因,可能不太适合检测基本类型,但是对于复杂类型有着不可替代的作用:

// 定义构造函数
function C(){} 
function D(){} 

var o = new C();

// true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof C; 

// false,因为 D.prototype不在o的原型链上
o instanceof D; 

o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
C.prototype instanceof Object // true,同上

C.prototype = {};
var o2 = new C();

o2 instanceof C; // true

o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.

D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true

因此检测复杂类型如下:

[] instanceof Array
true

/(1~9)?/ig instanceof RegExp
true

new Date instanceof Date
true

var a={};
a instanceof Object;
true

var f=function(){};
f instanceof Function;
true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hustchenshu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值