JS类型判断---typeof, constructor, instanceof, toString

JS中的数据类型

js中,根据存储的方式不一样(参见文末链接), 数据能够划分为如下两大类型:数组

  • 原始类型

    string, number, boolean, undefined, null, symbol函数

  • 引用类型

    Object (Array, Function, RegExp, Date)post

数据类型判断

判断数据的所属类型此处列举四种方法,并对每种方法使用的范围以及限制进行说明.若是对原型链还不熟悉的同窗,请先阅读相关的原型链知识(见文末)ui

  1. typeof

    typeof 通常仅用于判断原始类型(不包含null),返回值为该类型的字符串this

    console.log(typeof 'str');  // string
    console.log(typeof 1);      // number
    console.log(typeof true); // boolean
    console.log(typeof undefined); // undefined
    console.log(typeof Symbol()); // symbol
    复制代码

    注意: typeof不能用于判断原始类型中的null以及引用类型object,结果都会返回字符串object(Function类型除外,结果会返回function,但在在 IE 6, 7 和 8 上则返回object)spa

    console.log(typeof null);  // object
    console.log(typeof {}); // object
    console.log(typeof alert); // function
    console.log(typeof []); // object
    console.log(typeof new RegExp()); // object
    console.log(typeof new Date()); // object
    复制代码
  2. contructor

    constructor主要是利用原型上的prototype.constructor指向实例的构造函数来进行判断的prototype

    先定义一个构造函数Animal, 并new一个实例dog3d

    const Animal = function (name) {this.name = name};   // 声明一个构造函数
    let dog = new Animal('dog'); // 生成实例dog
    复制代码

    声明Animal函数的同时js会在Animal上挂载一个prototype对象,同时在prototype对象上会自动生成一个constructor属性并指向构造函数Animal,至关于:
    Animal.prototype.constructor === Animal // true ,根据原型链的查找原则, console(dog.prototype) // Animal 因此利用构造函数原型上的constructor属性能够判断当前实例是否为当前构造函数的实例,进而肯定数据所属类型:code

    console.log('1'.constructor === String);  // true
    console.log(new Number(1).constructor === Number); // true
    console.log(true.constructor === Boolean); // true
    console.log(alert.constructor === Function); // true
    console.log([].constructor === Array); // true
    console.log(new Date().constructor === Date); // true
    复制代码

    注意:对象

    1. null, undefined 是无效的对象,所以是不会有 constructor 存在的,这两种类型的数据须要经过其余方式来判断。
    2. 函数的 constructor 是不稳定的,这个主要体如今自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object

    constructor 判断类型的限制过多且不许确,容易出错,少用,或者不用!

  3. instanceof

    typeofconstructor 不一样, instanceof通常用于判断引用类型,返回值为布尔值, 例如:

    [] instanceof Array // true

    instanceof 是经过判断当前实例的原型与构造函数的原型是否为同一对象,进而肯定当前数据的类型,这样讲或许不够明了,咱们简单实现一下 instanceof

    const self_instanceof = function (instance, constructor) {
        let instance_proto = instance.__proto__;
        let constructor_proto = constructor.prototype;
    
        while(true) {
            // 找到终点返回false
           if (instance_proto === null) {return false};
           // 找到返回true
           if (instance_proto === constructor_proto) {return true};
            // 当实例与构造函数原型不相同, 沿着原型链继续向上查找
            instance_proto = instance_proto.__proto__;
        }
    }
    console.log([] instanceof Array)   // true
    console.log(self_instanceof([], Array))  // true
    复制代码

    当一个页面存在多个iframe时,也就是存在多个全局变量window,instanceof的判断会被来自不一样的iframe的数据所干扰,致使不可信

    假设:页面pageA 经过iframe内嵌了页面pageB, 此时pageB传递了一个数组 let arrB = []到页面 pageA, 若在pageA使用instanceof判断数组arrB会出现 arrB instanceof Array // false 主要缘由是由于 arrB 是由pageB上的Array构造出来的

    要避免这种问题可使用Es6提供的数组静态方法 Array.isArray, 或者咱们即将提到的toString方法进行判断
    Array.isArray(arrB) // true

  4. toString

    toStringObject.prototype上的一个方法, 经常使用方式为 Object.prototype.toString.call(target)
    返回值是 [object 类型]字符串,该方法基本上能判断全部的数据类型(自定义数据类型除外)

    // 定义判断类型函数
    let getType = target => Object.prototype.toString.call(target)
    
    console.log(getType('')); // [object String]
    console.log(getType(2)); // [object Number]
    console.log(getType(true)); // [object Boolean]
    console.log(getType(undefined)); // [object Undefined]
    console.log(getType(null)); // [object Null]
    console.log(getType(Symbol())); // [object Symbol]
    console.log(getType({})); // [object Object]
    console.log(getType([])); // [object Array]
    console.log(getType(alert)); // [object Function]
    console.log(getType(new RegExp())); // [object RegExp]
    console.log(getType(new Date())); // [object Date]
    复制代码

    该方法准确稳定,推荐使用

以上为类型判断的一些看法, 有不当之处, 还请大佬们指正!

相关知识点文章请参考:

详细图解 JavaScript 内存空间
JS原型链与继承别再被问倒了

相关文章
相关标签/搜索