• JS判断类型(typeof+constructor+toString)


    使用 typeof 运算符可以判断基本数据类型,我们在《JavaScript基本数据类型》中已经进行了演示,这里不再赘述。

    但是 typeof 有很多局限性,所以本节再介绍两种更灵活的方法,以应对高级开发可能遇到的各种复杂情况。

    使用 constructor

    constructor 是 Object 类型的原型属性,它能够返回当前对象的构造器(类型函数)。利用该属性,可以检测复合型数据的类型,如对象、数组和函数等。

    示例1

    下面代码可以检测对象和数组的类型,以此可以过滤对象、数组。

    1. var o = {};
    2. var a =[];
    3. if (o.constructor == Object) document.write("o 是对象");
    4. if (a.constructor == Array) document.write("a 是数组");

    结合 typeof 运算符和 constructor 原型属性,可以检测不同类型的数据。表中列举了常用类型数据的检测结果。

    值(value)typeof value(表达式返回值)value.constructor(构造函数的属性值)
    var value = 1“number”Number
    var value = “a”“string”String
    var value = true“boolean”Boolean
    var value = {}“object”Object
    var value = new Object()“object”Object
    var value = []“object”Object
    var value = new Array()“object”Object
    var value = function(){}“function”Function
    function className(){}; var value = new className();“object”Object

    示例2

    undefined 和 null 没有 constructor 属性,不能够直接读取,否则会抛出异常。因此,一般应先检测值是否为 undefined 和 null 等特殊值,然后再调用 constructor 属性。

    1. var value = undefined;
    2. console.log(value && value.constructor); //返回 undefined
    3. var value = null;
    4. console.log(value && value.constructor); //返回 null

    数值直接量也不能直接读取 constructor 属性,应该先把它转换为对象再调用。

    1. console.log(10.construetor); //抛出异常
    2. console.log((10).constructor); //返回 Number 类型
    3. console.log(Number(10).constructor); //返回 Number 类型

    使用 toString

    toString 是 Object 类型的原型方法,它能够返回当前对象的字符串表示。利用该属性,可以检测复合型数据的类型,如对象、数组、函数、正则表达式、错误对象、宿主对象、自定义类型对象等;也可以对值类型数据进行检测。

    示例1

    下面示例简单演示 toString() 方法的使用。

    1. var o = {}; //对象
    2. var a = [1,2]; //数组
    3. var f = function(){}; //函数
    4. console.log(o.toString()); //表示为 "[object Object]"
    5. console.log(a.toString()); //表示为 "1,2"
    6. console.log(f.toString()); //表示为 "function (){}"

    测试发现,不同类型对象调用 toString() 方法时返回的字符串格式并不统一,这是因为不同类型的子类在继承 Object 的原型方法 toString,时重写了该方法。如果在对象上调用 Object 的原型方法 toString(),就会返回统一格式的字符串表示。例如:

    1. var _toString = Object.prototype.toString; //引用 Objget 的原型方法 toString ()
    2. //使用 apply 方法在对象上动态调用 Object 的原型方法 toString ()
    3. console.log(_toString.apply(o)); //表示为 "[object Object]"
    4. console.log(_toString.apply(a)); //表示为 "[object Array]"
    5. console.log(_toString.apply(f)); //表示为 "[object Function]"

    示例2

    重写 toString() 方法,利用其返回的数据类型的字符串表示,可以设计一种更安全、更强健的类型检测方法,而且用户可以扩展检测类型的范围,如用户自定义类型、宿主类型等。

    设计思路

    首先,仔细分析不同类型对象的 toString() 方法返回值,会发现由 Object 的原型方法 toString() 直接返回的字符串格式如下:

    1. [object Class]

    其中,object 表示对象的基本类型,Class 表示对象的子类型,子类型的名称与该对象的构造函数名对应。例如,Object 对象的 Class 为 “Object”,Array 对象的 Class 为 “Array” , Function 对象的 Class 为 “Function”, Date 对象的 Class 为 “Date”,Math 对象的 Class 为 “Math”,Error 对象(包括 Error 子类)的 Class 为 “Error” 等。

    宿主对象也有预定义的 Class 值,如 “Window” “Document” 和 “Form” 等。用户自定义对象的 Class 为 “Object”。用户自定义的类型,可以根据该格式自定义类型表示。

    Class 值提供的信息与 constructor 属性值都能够检测数据类型,但是 Class 值是以字符串的形式提供这些信息,这在开发环境中是非常有用的。而使用 typeof 运算符进行类型检测,由于其返回的字符串表示比较有限,无法准确分辨 Object、Function 和 Array 等类型。

    实现代码

    下面是比较完整的数据类型检测函数。

    1. //强健的数据类型检测工具函数
    2. //参数:obj 表示待检测的值
    3. //返回值:返回字符串表示,格式与 typeof 运算符相同,
    4. //"undefined" "number" "boolean" "string" "function"
    5. //"regexp" "array" "date" "error" "object"或 "null"
    6. function typeOf(obj){
    7. var _toString = Object.prototype.toString; //引用 Object 的原型方法 toString () //列奉所有可能的类型字符串表示
    8. //模仿typeof运算符返回值,通过映射,统一字符串表示的值
    9. var _type ={
    10. "undefined" : "undefined",
    11. "number" : "number",
    12. "boolean" : "boolean",
    13. "string" : "string",
    14. "[object Function]" : "function0f",
    15. "[object RegExp]" : "regexp",
    16. "[object Array] " : "array",
    17. "[object Date]" : "date",
    18. "[object Error]" : "error"
    19. //在这里可以继续展开要检测的类型
    20. }
    21. //把值转换为字符串表示,然后匹配 _type 对象中的键值对,最后处理特殊值 null
    22. return _type[typeof obj] || _type[_toString.call(obj)] || (obj ? "object" :"null");
    23. }

    在上面检测函数中,先引用 Object 的原型方法 toString(),然后列举出所有可能存在的数据类型,把不同形式的字符串表示通过对象的键值对映射进行统一,模拟 typeof 运算符的返回值格式,设计所有类型返回的字符串表示都以小写的单个词来表示。接着使用 typeof 运算符或者 toString() 原型方法获取类型的字符串表示,再通过对象映射获得统一的字符串表示并返回。最后,单独处理特殊值 null,定义其返回值为”null”;对于不能映射的类型,则统一返回根类型表示”object”。

    应用代码

    1. var _abs = Math.abs; //引用 Math 对象的 Abs 方法
    2. console.log(typeOf(_abs)); //返回字符串表示 "function”
    3. //说明该方法为一个 Function 类型

    上述方法适用于 JavaScript 基本类型和内置对象,如果要检测宿主对象和自定义类型,则需要用户添加 _type 对象的键值对,以扩展类型检测的范围。

  • 相关阅读:
    web测试与app测试的区别
    Java动态编程之Instrumentation
    现在性价比高的运动耳机有哪些、性价比最高的蓝牙耳机排行榜
    后端工程师之路(8)-springboot
    计算机毕业设计ssm餐饮外卖系统v22fo系统+程序+源码+lw+远程部署
    Openresty(二十一)ngx.balance和balance_by_lua灰度发布
    Java面试题:SimpleDateFormat是线程安全的吗?使用时应该注意什么?
    高性能无线综合测试仪 无线电综合测试仪 ---TFN PM5100 100KHz-1GHz
    被一位读者赶超,手摸手 Docker 部署 ELK Stack
    力扣刷题学习SQL篇——1-12 树节点(使用行转列union/条件判断case when)
  • 原文地址:https://blog.csdn.net/unbelievevc/article/details/127976598