美文网首页
JS中的数据类型判断

JS中的数据类型判断

作者: 风起云涌Hal | 来源:发表于2018-01-31 14:45 被阅读40次

    一、typeof()

    首先看一批操作,我们可以思考下这些操作的结果会是什么:

    // 1.
    typeof null
    typeof undefined
    typeof true
    typeof 1
    
    // 2.
    typeof(new String('123'))
    typeof(Number('abc'))       
    typeof(new Number(123))
    
    // 3.
    typeof []
    typeof(Array)
    typeof(new Array)
    
    // 4.
    typeof function() {}
    typeof(Function)
    typeof(new Function)
    
    // 5.
    typeof {}
    typeof Object
    typeof new Object()
    

    在浏览器中执行上面的操作后,可以得到如下结果:

    // 1.
    typeof null // "object"
    typeof undefined // "undefined"
    typeof true // "boolean"
    typeof 1 // "number"
    
    // 2.
    typeof(new String('123')) // "object"
    typeof(Number('abc')) // "object"
    typeof(new Number(123)) // "object"
    
    // 3.
    typeof [] // "object"
    typeof(Array) // "function"
    typeof(new Array) // "object"
    
    // 4.
    typeof function() {} // "function"
    typeof(Function) // "function"
    typeof(new Function) // "function"
    
    // 5.
    typeof {} // "object"
    typeof Object // "function"
    typeof new Object() // "object"
    

    typeof操作符返回一个字符串,指示未经计算的操作数的类型。有部分数据类型比较特殊:

    • null
      在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null的类型标签也成为了 0,typeof null就错误的返回了"object"

    • 正则表达式
      对正则表达式字面量的类型判断在某些浏览器中不符合标准:

    typeof /s/ === 'function'; // Chrome 1-12 , 不符合 ECMAScript 5.1
    typeof /s/ === 'object'; // Firefox 5+ , 符合 ECMAScript 5.1
    
    • 未声明的变量
      在 ECMAScript 2015 之前,typeof总是保证为任何操作数返回一个字符串。但是,除了非提升,块作用域的letconst之外,在声明之前对块中的letconst变量使用typeof会抛出一个ReferenceError。而未声明的变量,使用typeof会返回“undefined”。
    typeof undeclaredVariable === 'undefined';
    typeof newLetVariable; let newLetVariable; // ReferenceError
    typeof newConstVariable; const newConstVariable = 'hello'; // ReferenceError
    
    • document.all
      所有当前的浏览器都暴露了一个类型为 undefined 的非标准宿主对象document.all
    typeof document.all === 'undefined';
    

    上述typeof的操作,我们可以发现在很大程度上,typeof无法获取到准确的类型(譬如typeof null === "object"; typeof [] === "object";)。因而我们介绍一种更为通用的判断类型的方式:

    二、Object.prototype.toString.call()

    我们将上一节中的所有操作替换为Object.prototype.toString.call

    // 1.
    Object.prototype.toString.call(null) // "[object Null]"
    Object.prototype.toString.call(undefined) // "[object Undefined]"
    Object.prototype.toString.call(true) // "[object Boolean]"
    Object.prototype.toString.call(1) // "[object Number]"
    
    // 2.
    Object.prototype.toString.call(new String('123')) // "[object String]"
    Object.prototype.toString.call(Number('abc')) // "[object Number]"
    Object.prototype.toString.call(new Number(123)) // "[object Number]"
    
    // 3.
    Object.prototype.toString.call([]) // "[object Array]"
    Object.prototype.toString.call(Array) // "[object Function]"
    Object.prototype.toString.call(new Array) // "[object Array]"
    
    // 4.
    Object.prototype.toString.call(function() {}) // "[object Function]"
    Object.prototype.toString.call(Function) // "[object Function]"
    Object.prototype.toString.call(new Function) // "[object Function]"
    
    // 5.
    Object.prototype.toString.call({}) // "[object Object]"
    Object.prototype.toString.call(Object) // "[object Function]"
    Object.prototype.toString.call(new Object()) // "[object Object]"
    

    从以上结果我们看到,使用Object.prototype.toString.call方法能够得到更为准确的类型。

    三、ES6中Object.prototype.toString.call()的拓展

    如果我们定义了一个类,然后实例化这个类,那么这个实例的类型是否应该为这个类呢?如下:

    function Person(name) {
        this.name = name;
    }
    var p = new Person('Hal');
    
    typeof p; // "object"
    Object.prototype.toString.call(p); // "[object Object]"
    

    这个与我们想要的结果不大一样,我们希望执行Object.prototype.toString.call(p)时能够获得实际的类型:"[object Person]"。ES6中,提供了一种方式:

    Person.prototype[Symbol.toStringTag] = 'Person';
    

    再次执行Object.prototype.toString.call(p)时我们能够获得想要的结果:"[object Person]"。这是因为在该对象上面调用Object.prototype.toString方法时,如果[Symbol.toStringTag]属性存在,它的返回值会出现在toString方法返回的字符串之中,表示对象的类型。

    综上所述,我们判断数据类型时,推荐使用Object.prototype.toString.call()这种方式。

    相关文章

      网友评论

          本文标题:JS中的数据类型判断

          本文链接:https://www.haomeiwen.com/subject/plrkzxtx.html