资讯专栏INFORMATION COLUMN

javascript判断数据类型

Lyux / 594人阅读

摘要:操作符刚说完,肯定又有人想用,但是,真的有用吗操作符用来比较两个操作数的构造函数,运算符与运算符相似,用于识别正在处理的对象的类型。

题目

实现一个函数typeof(),输入一个数据,返回数据的基本类型。
如:

typeof([]) => array
typeof({}) => object
typeof("") => string
等等
解析

由于javascript这门语言辉(keng)煌(die)的历史,所以连这种简单的需求都需要自己来实现,唉,说多了,都是泪啊。

这儿题目相对来说应该是比较简单的,但是也是有不少坑,想要真正实现的很好,还是需要用到不少知识的。

一开始,肯定有人想到使用typeof,顾名思义嘛,就是判断数据的类型,但是,可是,实际真的是这样吗?

typeof操作符

typeof 操作符(和 instanceof 一起)或许是 JavaScript 中最大的设计缺陷, 因为几乎不可能从它们那里得到想要的结果。 --javascript秘密花园

尽管instanceof 还有一些极少数的应用场景,typeof 只有一个实际的应用,就是用来检测一个对象是否已经定义或者是否已经赋值,而这个应用却不是用来检查对象的类型。(好吧,这个其实貌似也并没有什么卵用。。。)
在下面表格中,Type 一列表示 typeof 操作符的运算结果。其中,JavaScript 标准文档中定义: [[Class]] 的值只可能是下面12个字符串中的一个: Arguments, Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, String。可以看到,这个值在大多数情况下都返回 "object"。

Value Class Type
"foo" String string
new String("foo") String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function("") Function function
/abc/g RegExp object (function in Nitro/V8)
new RegExp("meow") RegExp object (function in Nitro/V8)
{} Object object
new Object() Object object

##### 测试为定义变量

typeof foo !== "undefined"

上面代码会检测 foo 是否已经定义;如果没有定义而直接使用会导致 ReferenceError 的异常。 这是 typeof 唯一有用的地方。

instanceof 操作符

刚说完,typeof,肯定又有人想用instanceof,但是,instanceof真的有用吗?
instanceof 操作符用来比较两个操作数的构造函数,instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。具体的可以看看这个JavaScript instanceof 运算符深入剖析。
因此,instanceof在判断一个对象是不是一个类的实例只有在比较自定义的对象时才有意义。 如果用来比较内置类型,将会和 typeof 操作符 一样用处不大。

比较自定义对象
function Foo() {}
function Bar() {}
Bar.prototype = new Foo();

new Bar() instanceof Bar; // true
new Bar() instanceof Foo; // true

// 如果仅仅设置 Bar.prototype 为函数 Foo 本身,而不是 Foo 构造函数的一个实例。
Bar.prototype = Foo;
new Bar() instanceof Foo; // false
instanceof 比较内置类型

但是,不是通过构造函数创建的对象使用instanceof比较,那得到的,可能就不是你想要的结果。

new String("foo") instanceof String; // true
new String("foo") instanceof Object; // true

"foo" instanceof String; // false
"foo" instanceof Object; // false
注意

还有有一点需要注意,instanceof 用来比较属于不同 JavaScript 上下文的对象(比如,浏览器中不同的文档结构)时将会出错, 因为它们的构造函数不会是同一个对象。

看到这里,是不是很震惊?你所知道的知道的方法,都是错的。。。唉,当初我知道了这个也是泪流满面啊。。。

解决方法 Object.prototype.toString

javascript对象的内部属性 [[Class]] 的值就包含有j其对象的类型,为了获取对象的 [[Class]],我们需要使用定义在 Object.prototype 上的方法 toString。

function is(type, obj) {
    var clas = Object.prototype.toString.call(obj).slice(8, -1);
    return obj !== undefined && obj !== null && clas === type;
}

is("String", "test"); // true
is("String", new String("test")); // true

Object.prototype.toString 返回一种标准格式字符串,所以上例可以通过 slice 截取指定位置的字符串,如下所示:

Object.prototype.toString.call([])    // "[object Array]"
Object.prototype.toString.call({})    // "[object Object]"
Object.prototype.toString.call(2)    // "[object Number]"
看看大神的解决方案

如果我没记错,在jQueryunderscore等库中都有判断数据类型的函数,可能平时大家也就用用,没有仔细了解过它们的底层是怎么实现的,

我们要会使用框架,但不要依赖框架

以后大家再碰到类似的问题的时候,不妨查看一下这些成熟框架或库的实现源码,这里,我抛出jQuery的实现源码,抛砖引玉。

var class2type = {} ;
"Boolean Number String Function Array Date RegExp Object Error".split(" ").forEach(function(e,i){
    class2type[ "[object " + e + "]" ] = e.toLowerCase();
}) ;
//当然为了兼容IE低版本,forEach需要一个polyfill,不作细谈了。
function _typeof(obj){
    if ( obj == null ){
        return String( obj );
    }
    return typeof obj === "object" || typeof obj === "function" ?
    class2type[ Object.prototype.toString.call(obj) ] || "object" :
        typeof obj;
}
结论:

看源码是程序员快速成长的重要方式。

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

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

相关文章

  • 如何判断JavaScript数据类型

    摘要:本文将讲解我目前所知道的判断数据类型的方法。数据类型一共有种除了之外的种属于原始数据类型。等价于问题四的返回值是什么答案。 本文将讲解我目前所知道的判断JavaScript数据类型的方法。JavaScript数据类型一共有7种: Undefined Null Boolean String Symbol Number Object 除了Object之外的6种属于原始数据类型。有时,我...

    jackzou 评论0 收藏0
  • javascript如何判断变量的数据类型

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

    曹金海 评论0 收藏0
  • javascript 数据类型判断 (常见库的数据类型判断源码的分析)

    摘要:对象类型常见的有,,,正则新增自己提供的乐行判断如果不对对象做严格区分使用。的实现使用了原型继承的表示左表达式,表示右表达式,它是用是否等于来判断对象的类型的。常见框架和库的实数据类型判断测试这里将的实现原理抽取出来,用原生实现。 JavaScript一共有六种数据类型,分为原始类型(又名基本类型)和对象类型(又名引用类型) 原始类型有五种,分别为number,string,boole...

    libin19890520 评论0 收藏0
  • JavaScript instanceof运算符深入分析

    摘要:注意基本变量类型不是对象类型,只有基本包装类型才是对象类型。至于显示的原型,在里用属性表示,这个是原型继承的基础知识,在这里就不在叙述了。 前言 如果你要开发一个复杂的产品,那么肯定少不了使用面向对象机制,当然也避不开 Javascript 里面的继承,instanceof 运算符是原生 Javascript 语言中用来判断实例继承的操作符。所以我们有必要深入理解该运算符! inst...

    zhangyucha0 评论0 收藏0
  • JavaScript数据类型判断

    摘要:日常工作中经常会有判断数据类型的需求,这里简单介绍下我平时判断数据类型的几种方式。当使用检测基本类型时,会始终返回操作符确实解决了类型判断的问题,但还是有一些不足之处。此外,只能返回,并不能直接返回数据的类型。 JavaScript中有5种基本数据类型:undefined,String,Boolean,Number,Null,以及一种复杂数据类型Object。日常工作中经常会有判断数据...

    luckyyulin 评论0 收藏0
  • JavaScript中,如何判断数组是数组?

    摘要:比如我们今天要讨论的,在当中如何判断一个数组是数组。在数组的原型链上也能找到构造函数由上面的几行代码可以看出,使用运算符可以分辨数组和对象,可以判断数组是数组。用判断实例化的数组拥有一个属性,这个属性指向生成这个数组的方法。 如果你没有注意过这个问题,那么这个标题应该会让你感到困惑,判断数据类型这么基础的问题能有什么坑呢? 少年,你不能太天真了,我们朝夕面对的这门语言,可是JavaSc...

    kohoh_ 评论0 收藏0

发表评论

0条评论

Lyux

|高级讲师

TA的文章

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