资讯专栏INFORMATION COLUMN

javascript如何判断变量的数据类型

曹金海 / 422人阅读

摘要:除和外,所有的数据类型都是可以转化为对象,而如果是对象,就肯定有构造函数。特性因为和没有构造函数,因此不能用此方法来判断。由于同一条原型继承链上的各个对象的构造函数都不一样,因此,此方法可以区分开继承链上的各个自定义数据类型。

typeof 用法示例
var arr = [];
typeof arr;    //"object"
typeof(arr);    //"object"

typeof实际上是一个一元运算符,因此可以用上述代码所示的两种用法。

typeof所支持的数据类型

从上表可以看出,typeof支持的数据类型还是比较齐全的,除了俩比较特殊以外:

Null使用typeof返回object,这跟我们的认知还是有一定差距的,这是javascript的一个设计上的bug,ECMAScript 6中有提议修改此bug,但已经被否决了;不过只要加个逻辑非!运算符,就能把Null这种情况给排除了。

除了function以外,其它具体的对象类型都无法判断出来。

typeof浏览器兼容性注意点 对正则表达式字面量的类型判断在某些浏览器中不符合标准:
typeof /s/ === "function"; // Chrome 1-12 , 不符合 ECMAScript 5.1
typeof /s/ === "object"; // Firefox 5+ , 符合 ECMAScript 5.1
IE 宿主对象是对象而不是函数

在 IE 6, 7 和 8 中,大多数的宿主对象是对象,而不是函数,例如:

typeof alert === "object"
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

instanceof是一个二元运算符。

instanceof总结

javascript中的原生对象以及用户的自定义对象基本上都能利用instanceof识别出来,除了NullUndefined

instanceof无法区分开同一原型继承链:

function A(){
    //...
}

function B(){
    //...
}

function C(){
    //...
}

var a = new A();
B.prototype = a;

var b = new B();
C.prototype = b;

var c = new C();

c instanceof A;    //true
c instanceof B;    //true
c instanceof C;    //true
Object.prototype.toString.call 用法示例
function type(obj) {
  return Object.prototype.toString.call(obj).slice(8, -1);
}
type(1);    //"Number"
type("1");    //"String"
type(true);    //"Boolean"
type(undefined);    //"Undefined"
type(null);    //"Null"
type({});    //"Object"
type([]);    //"Array"
type(new Date);    //"Date"
type(/d/);    //"RegExp"
type(function() {});    //"Function"

function Point(x, y) {
    //
}
type(new Point(1, 2));    //"Object"
用法解析

从以上用法示例可以看出,这个基于Object.prototype.toString.call封装好的函数用法跟typeof非常相似,但是在支持的数据类型上比typeof强多了,所有的javascript原生数据类型都能判断出来。遗憾的是,Object.prototype.toString.call也不是万能的方案:无法识别自定义的对象类型。
Object.prototype.toString.call实际上是返回这样形式的值:

Object.prototype.toString.call(1);    //"[object Number]"
Object.prototype.toString.call("1");    //"[object String]"

因此只要用slice方法把数据类型“切”出来就成了。

constructor(构造函数) 用法示例
/*
* 获取对象构造函数名称
*/
function getConstructorName(obj){
    return obj && obj.constructor && obj.constructor.toString().match(/functions*([^(]*)/)[1]; //利用obj && obj.constructor来判断null和undefined
}
用法解析

这是一种非常巧妙的判断数据类型的方法——利用构造函数判断数据类型,这是基于javascript的特性/规范:

对象的构造函数名就是该数据类型。

NullUndefined外,所有的数据类型都是/可以转化为对象,而如果是对象,就肯定有构造函数。

特性

因为NullUndefined没有构造函数,因此不能用此方法来判断。

由于同一条原型继承链上的各个对象的构造函数都不一样,因此,此方法可以区分开继承链上的各个自定义数据类型。

function A(){
    //...
}

function B(){
    //...
}

function C(){
    //...
}

var a = new A();
B.prototype = a;

var b = new B();
C.prototype = b;

var c = new C();

getConstructorName(a);    //A
getConstructorName(b);    //B
getConstructorName(c);    //C
总结

以上这四种方法都有不同程度的缺陷,如果从实用性的角度来考虑,可以综合一下:

function type(obj) {console.dir(obj);
  if(!obj) {
    return Object.prototype.toString.call(obj).slice(8, -1);
  }
  return obj.constructor.toString().match(/functions*([^(]*)/)[1];
}
var t = type(1) // t==="number"
var t = type(new Number(1)) // t==="number"
var t = type("abc") // t==="string"
var t = type(new String("abc")) // t==="string"
var t = type(true) // t==="boolean"
var t = type(undefined) // t==="undefined"
var t = type(null) // t==="null"
var t = type({}) // t==="object"
var t = type([]) // t==="array"
var t = type(new Date) // t==="date"
var t = type(/d/) // t==="regexp"
var t = type(function(){}) // t==="function"
参考资料

typeof - JavaScript | MDN
instanceof - JavaScript | MDN

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91594.html

相关文章

  • 分析 JavaScript 数据类型变量

    摘要:基本数据类型在中,基本数据类型有种,即数值字符串布尔值。两个布尔值转为数值进行比较。对于对象和布尔值,调用它们的方法得到对应的字符串值,然后进行字符串相加。减法对于字符串布尔值或者,自动调用,转换结果若为,那么最终结果为。 这篇文章,来聊聊 JS 中的数据类型与变量。这是在学习 JS 时最基础的一类问题,但却很重要。希望我的分享有帮助到你。 文章开头,我先提几个面试中遇到的问题: 比如...

    Mike617 评论0 收藏0
  • 关于javascript类型判断那些疑惑

    摘要:对于复杂类型它的每个实例都有属性。当检测实例时优于因为能检测这段代码是从的。补充以下结果,发现第三种方法也能正确判断出。我们知道结果是那如何判断两个变量呢比较两个变量,使用的即可。 Javascript中数据类型分为两种: 简单数据类型:Undefined, NULL, Boolean, Number, String 复杂数据类型:Object 接下来我们就来看看怎么做数据类型判别...

    李增田 评论0 收藏0
  • JavaScript入门

    摘要:介绍编程数据结构,算法,内存分配表单验证需要一门语言可以直接运行在浏览器中,来完成表单验证的功能。 Javascript介绍编程(数据结构,算法,内存分配)表单验证 需要一门语言可以直接运行在浏览器中,来完成表单验证的功能。 浏览器厂商 网景 firefox js 标准 js解释器 IE js js解释器 google js j...

    wangdai 评论0 收藏0
  • js面试题(上)

    https://segmentfault.com/a/11... 原型 / 构造函数 / 实例 对原型的理解 我们知道在es6之前,js没有类和继承的概念,js是通过原型来实现继承的。在js中一个构造函数默认自带有一个prototype属性, 这个的属性值是一个对象,同时这个prototype对象自带有一个constructor属性,这个属性指向这个构造函数,同时每一个实例 都有一个__proto...

    leap_frog 评论0 收藏0
  • javascript基础篇小结

    摘要:表示尚未存在的对象是一个有特殊意义的值。可以为变量赋值为,此时变量的值为已知状态不是,即。用来初始化变量,清除变量内容,释放内存结果为但含义不同。且它俩与所有其他值比较的结果都是。,需要两个操作数同时转为。 转载请声明出处 博客原文 随手翻阅以前的学习笔记,顺便整理一下放在这里,方便自己复习,也希望你有也有帮助吧 第一课时 入门基础 知识点: 操作系统就是个应用程序 只要是应用...

    hiyang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<