zoukankan      html  css  js  c++  java
  • 类与类型 获取类型几种方式!!

    说到类型,JavaScript 定义了少量的数据类型: null undefined 布尔值 数字 字符串 函数 和 对象。

    假如要区分值得类型,无疑 typeof 首选 。如下

      

     1 typeof 1
     2 typeof "string"
     3 typeof true
     4 typeof null
     5 typeof undefined
     6 typeof {}
     7 typeof /W/
     8 
     9 
    10 
    11 :1 number
    12 :2 string
    13 :3 boolean
    14 :4 object
    15 :5 undefined
    16 :6 object
    17 :7 object
    View Code

    在以面向对象思想设计中,我们往往更希望将类作为类型来对待,这样就可以根据对象所属的类来区分它们。JavaScript 核心内置对象可以通过 class 属性来得到其类型,但是这种方式对于自定义对象来说是不能通过 class 属性来区分对应的类型。

      看看下面的实战代码-: 前面章节提到过 class 属性是不能直接获取,只能借助 toString 方式来获取,但是在 部分对象覆盖了 toString 例如 Date Math 等 那可以通过 call 或 apply 达到统一道理

    function classOf(o) {
        if (o == null) return "Null";
        if (o === "undefined") return "undefined";
        return Object.prototype.toString.call(o).slice(8, -1);
    }
    function User() {}
    
    console.log(classOf([]))
    console.log(classOf(new Date()))
    console.log(classOf(new RegExp()))
    console.log(classOf(Math))
    console.log(classOf({}));
    console.log(classOf(new User()))
    
    Array
    Date
    RegExp
    Math
    Object
    Object

    对于自定义对象是没有办法判断其属于什么类型,下面主要介绍下三个属性: instanceof运算符 、constructor属性、构造函数的名字。 但是每种技术都不甚完美。

      instanceof 语法格式

        操作符左边为实例对象,右边为定义构造函数。 

      先来看看下面的简单实例: 

    function A() {};
    function B() {};
    var a = new A();
    console.log(a instanceof A); // true
    A.prototype = new B();
    console.log(a instanceof A); //false

      上面主要定义两个构造函数,然后声明一个变量a 再更改A的原型对象指向。 从上面两个输出来看,可以得出,只要 A.prototype 在a的原型链上的对象,不管是直接继承还是间接继承,其都会返回 true; 

     可以用下图表示:

     

     根据得出结论可以看出,在更该之后其原型 A.prototype 指向新的实例,并不存在于a对象原型链上。 从instanceof操作符右侧虽然制定的构造函数,但是其并不是根据其来进行判断,而是检测的是他们的继承关系。 那么有没有直接判断某个对象是不是继承另一个对象尼?

      Object.isPrototypeOf()   

    function A() {};
    
    function B() {};
    var a = new A();
    console.log(A.prototype.isPrototypeOf(a));
    A.prototype = new B();
    console.log(A.prototype.isPrototypeOf(a));
    
    true
    false

    instanceof 与 isPrototypeOf 两者缺点相同,不能通过对象获取类的名称,而是只能判断某个对象是不是存在其原型链上。 

    注意: 在多框架的情况下, 例如 宿主对象 Array ,在每个框架都拥有一套不同的构造函数,所以在进行A框架-> B框架传递一个Array实例时, 使用 instanceof 会返回false

    constructor 属性

      顾名思义 获取对象的构造函数。构造函数是类的公共标识,所以判断某个实例是不是属于某个类可以直接使用 constructor属性  

    先来看看其使用:如下实例 

    function Person() {}
    
    function classOf(o) {
        var con = o.constructor;
        switch (con) {
            case Number:
                console.log("Number");
                break;
            case String:
                console.log("String");
                break;
            case Boolean:
                console.log("Boolean");
                break;
            case Array:
                console.log("Array");
                break;
            case RegExp:
                console.log("RegExp");
                break;
            case Date:
                console.log("Date");
                break;
            case Object:
                console.log("Object");
                break;
            case Person:
                console.log("Person");
                break;
        }
    }
    
    classOf(1);
    classOf("string");
    classOf(true);
    classOf([]);
    classOf(/w/);
    classOf(new Date());
    classOf({});
    classOf(new Person());
    
    Number
    String
    Boolean
    Array
    RegExp
    Date
    Object
    Person

     注意:这种方式也是存在一个问题,在多个上下文环境的(多框架的情况下),其是不能正确返回的问题。

      

    构造函数名称

       在instanceof 和 constructor 在针对多中上下文的情况下,都会出现错误。如果在多框架下,唯一解决办法是可以通过根据构造函数名称而不已构造函数本省作为公共标识。

    JavaScript中提供非标准的 name 属性,在某些浏览器中不支持name属性时,可以通过先把函数转换为字符串,再进行比较。  //主要获取函数名称

    Function.prototype.getName = function() {
        return this.name || A.toString().match(/w+s*([^()*])/)[1];
    }

     注意:这种方式有一个问题是,当函数为匿名函数时,会返回空值。

       但是如果是对象(除函数外)时,可以利用其 class 属性 ,而 class 属性获取方式为: 

    function classOf(o) {
        if (o == null) return "Null";
        if (o === "undefined") return "undefined";
        return Object.prototype.toString.call(o).slice(8, -1);
    }

    结合上述几种方式,可以用来获取其type名称

    function type(o) {
        var t, c, n;
        if (o === null) return "Null";
        if (o != o) return "NuN";
        /**
         * 通过这种方式:可以区分
         */
        if ((t = typeof o) !== "object") return t;
    
        //可以区分大部分的内置对象 在大多数情况下 都覆写了toString()
        if ((c = classOf(o)) !== "Object") return c;
        
        //自定义对象 并且存在constructor和函数名称属性
        if (o.constructor && typeof o.constructor === "function" && (n = o.constructor.getName())) return n;
        return "Object";
    }
  • 相关阅读:
    POJ 1611
    [Erlang24]使用zotonic搭建网站记录
    [Erlang23]怎么有效的遍历ETS表?
    [Erlang22]如何按规则位数输出数字
    [Git00] Pro Git 一二章读书笔记
    十分钟用HTML&CSS让博客园变得高大上
    [Erlang21]Erlang性能分析工具eprof fporf的应用
    [Erlang20]一起攻克Binary
    [Erlang19]Erlang的config文件读取效率问题
    [Erlang18]教练!又发现Erlang Shell里面的神奇函数一只
  • 原文地址:https://www.cnblogs.com/czhyuwj/p/5908786.html
Copyright © 2011-2022 走看看