欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

选择适合的类型判断方式

程序员文章站 2022-09-04 14:06:21
类型判断是个常见问题,有多种不同的判断方式,每种方式都有适用的场景。 typeof 操作符返回一个字符串,表示未经计算的操作数的类型。 或者 都可以,括号为可选的。 类型 | 结果 : |: : Undefined | "undefined" ==Null== | =="object"== Bool ......

类型判断是个常见问题,有多种不同的判断方式,每种方式都有适用的场景。

typeof

typeof 操作符返回一个字符串,表示未经计算的操作数的类型。

typeof operand 或者 typeof (operand) 都可以,括号为可选的。

类型 结果
undefined "undefined"
==null== =="object"==
boolean "boolean"
number "number"
string "string"
symbol(ecmascript 6 新增) "symbol"
==函数对象== =="function"==
任何其他对象 "object"

typeof 会将 nullobject 都返回为 "object", 这样就无法区分具体的对象类型(array , date , error等)。

注意:其中函数对象特别返回为"function" 。

    // 'number'
    typeof 1
    typeof nan
    typeof infinity    
    
    // 'string'
    typeof '1'
    
    // 'boolean'
    typeof true
    
    // 'undefined'
    typeof undefined
    
    // 'symbol'
    typeof symbol(1)
    
    // 'object'
    typeof null
    
    // 'object'
    typeof {}
    typeof []
    typeof new date()
    typeof new number(1)

    // 'function'
    typeof function(){}
    typeof class a {}
    typeof math.sin

instanceof

instanceof运算符用于测试构造函数的prototype属性是否出现在==对象==的原型链中的任何位置

object instanceof constructor

  • 左侧参数如果不是对象,将返回false
  • 右侧参数如果不是构造函数,将报错
    let x = 1;
    let y = new number(1);
    
    x instanceof number // false   1 不是对象
    y instanceof number // true  new number(1)为对象

    // 虽然这种方式测试“x”有原型,但是应该是在获取的时候,自动进行了对象包装, 其实获取的是 new number(1)
    x.__proto__ === object.getprototypeof(x) === number.prototype 

    // 沿着原型链比对  y.__proto__.__proto__ === object.prototype , 故返回true
    y instanceof object // true

instanceof 的判断结果会随着对象或者构造函数的改变而不同,而不是固定的值

    class a {}
    class b {}
    let a = new a();

    a instanceof a  // true
    a instanceof b  // false

    // 修改a的 __proto__ 指向
    a.__proto__ = b.prototype

    a instanceof a  // false
    a instanceof b  // true

instanceof不能判断原始数据类型,但是可以用来判断对象具体是那种类型

    [] instanceof array // true
    new error() instanceof error // true
    (/[1-9]+/) instanceof regexp // ture
    new date() instanceof date // true

    let x = document.queryselectorall('h1')
    x instanceof nodelist // true
    ···

object.prototype.tostring()

tostring()方法返回一个表示该对象的字符串。默认情况下,tostring()方法被每个object对象继承。如果此方法在自定义对象中未被覆盖,tostring() 返回 "[object type]" ,其中type是对象的类型

待检测对象也许会重写tostring()方法,这时就无法检测tostring来判断类型。所以要保证能够检测类型,需要调用object.prototype.tostring来进行判断。如下:

    let x = function(x) {
        this.name = x
    }

    let x =  new x(); 

    x.tostring() // "[object,object]"  使用继承的tostring
    object.prototype.tostring.call(x) // "[object,object]"

    x.prototype.tostring = function() { // 重写父类的tostring方法
        return 'not type'
    }

    x.tostring() // "not type"   使用重写后的tostring , 就不再返回类型

    object.prototype.tostring.call(x) // "[object,object]"

返回的" [ object, type]" 不好分辨,可以进行特殊的处理,直接返回类型名称。

    // 获取类型
    function gettype(target){
        let types = {}
        let temp = object.prototype.tostring.call(target)
        //types映射类型
        'boolean number string null undefined symbol function array date regexp object error nodelist'.split(' ').map(value => {
            types[`[object ${value}]`] = value.tolowercase()
        })

        if (types[temp]) {
            return types[temp]
        }else if (temp.indexof('html') !== -1) { // 判断是否为dom元素
            return 'element' 
        }else {
            return
        }
    }
    
    // 测试

    gettype(1) //  "number"
    gettype(symbol(1)) // "symbol"
    gettype([]) // "array"
    gettype({}) // "object"
    gettype(document.queryselectorall('div')) // "nodelist"

用如上方法,就可以便捷的获取到类型名称了。

其他api

判断值是否是 nan number.isnan()

number.isnan() 判断值是否是 nan,和全局函数 isnan() 相比,该方法不会强制将参数转换成数字,只有在参数是真正的数字类型,且值为 nan 的时候才会返回 true。

    number.isnan(nan);        // true
    number.isnan(number.nan); // true
    number.isnan(0 / 0)       // true
    
    number.isnan(null);       // false
    number.isnan(37);         // false
    number.isnan("37");       // false

    number.isnan("nan");      // false 不会隐式转换
    window.isnan('nan')       // true 会隐式转换

判断值是否为有穷数 number.isfinite()

number.isfinite() 方法用来检测传入的参数是否是一个有穷数(finite number)。 和全局的 isfinite() 函数相比,这个方法不会强制将一个非数值的参数转换成数值,这就意味着,只有数值类型的值,且是有穷的(finite),才返回 true

    number.isfinite(infinity);  // false
    number.isfinite(nan);       // false
    number.isfinite(-infinity); // false

    number.isfinite(0);         // true
    number.isfinite(2e64);      // true

    number.isfinite('0');       // false, 全局函数 isfinite('0') 会返回 true

判断值是否为整数 number.isinteger()

number.isinteger() 方法用来判断给定的参数是否为整数。

    number.isinteger(0);         // true
    number.isinteger(1);         // true
    number.isinteger(-100000);   // true

    number.isinteger(0.1);       // false
    number.isinteger(math.pi);   // false

    number.isinteger(infinity);  // false
    number.isinteger(-infinity); // false
    number.isinteger("10");      // false 不会进行隐式转换
    number.isinteger(true);      // false
    number.isinteger(false);     // false
    number.isinteger([1]);       // false