原生JavaScript类型判断

第1问:js中的数据类型有哪些?

    1.1 原始数据类型:共有7种

        Boolean Number String undefined null Bigint Symbol

    1.2 引用数据类型:1种

        Object对象(包括普通Object、Function、Array、Date、RegExp、Math)

第2问:你真的懂typeof吗?

    2.1  typeof的作用?

        区分数据类型返回7种数据类型:number、string、boolean、undefined、object、function,以及ES6新增的symbol

    2.2 typeof能正确区分数据类型吗?

        不能。对于原始类型,除null都可以正确判断;对于引用类型,除function外,都会返回"object"

    2.3 typeof注意事项

        typeof返回值为·格式,注意类似这种考题: typeof(typeof(undefined)) -> "string"

        typeof未定义的变量不会报错,返回"undefiend"

        typeof(null) -> "object": 遗留已久的bug

        typeof无法区别数组与普通对象: typeof([]) -> "object"

        typeof(NaN) -> "number"
        常见变量的数据类型:
        console.log(typeof(b));// b未定义,返回undefined

        console.log(typeof(undefined)); // undefined

        console.log(typeof(NaN)); // NaN 为number类型

        console.log(typeof(null)); // object

        var a = '123abc'; 

        console.log(typeof(+a)); // +a 类型转换为NaN

        console.log(typeof(!!a)); // boolean

        console.log(typeof(a + "")); // string

        console.log(typeof(typeof(null)));// string

        console.log(typeof(typeof({})));// string
 

第3问:什么是instanceof?你能模拟实现一个instanceof吗?

   3.1  instanceof可以准确判断对象的类型,其内部机制是判断对象的原型链上是否存在该类型的原型。

    instanceof常用来判断A是否为B的实例:

    // A是B的实例,返回true,否则返回false

    // 判断A的原型链上是否有B的原型

        A instanceofB

    3.2 模拟实现instanceof

    思想:沿原型链往上查找

    function instance_of(Case, Constructor) {

        // 基本数据类型返回false

        // 兼容一下函数对象

        if ((typeof(Case) !== 'object' && typeof(Case) !== 'function') || Case === 'null') return false;

        let CaseProto = Object.getPrototypeOf(Case);

        while (true) {

            // 查到原型链顶端,仍未查到,返回false

            if (CaseProto == null) return false;

            // 找到相同的原型

            if (CaseProto === Constructor.prototype) return true;

            CaseProto = Object.getPrototypeOf(CaseProto);

        }

    }

    测试:

        console.log(instance_of(Array, Object)) // true

        function User(name){

            this.name = name;

        }

        const user = new User('zc');

        const vipUser = Object.create(user);

        console.log(instance_of(vipUser, User)) // true
 

第4问:如何区分数组与对象?instanceof判断是否是数组可靠吗?

    4.1 Array.isArray()

        如果不存在Array.isArray()呢?可以借助Object.prototype.toString.call()实现,这种实现方式兼容性最好

        if (!Array.isArray) {

            Array.isArray = function(o) {

                return typeof(o) === 'object' 

                   && Object.prototype.toString.call(o) === '[object Array]';

            }

        }

    4.2 instanceof判断
        判断方式

            arr instanceof Array // 如果为true,则arr为数组

        instanceof判断数组如此之简单,为何不推荐使用那?

            instanceof操作符的问题在于,如果网页中存在多个iframe,那便会存在多个Array构造函数,此时判断是否是数组会存在问题。
 

第五问:如何判断一个数是否为NaN?

    5.1 NaN有个非常特殊的特性,NaN与任何值都不相等,包括它自身

        NaN === NaN // false

        鉴于这个独特的特性,可以手撕一个比较简单的判断函数

            function isNaN(x) {

                return x != x;

            }
    5.2 isNaN方法:不推荐使用。MDN对它的介绍是:isNaN函数内包含一些非常有趣的规则。

        isNaN的有趣机制:会先判断参数是不是Number类型,如果不是Number类型会尝试将这个参数转换为Number类型,之后再去判断是不是NaN。

    举个例子:

    // 是不是很有趣

    console.log(isNaN([])) // false

    console.log(isNaN([1])) // false

    console.log(isNaN([1, 2])) // true 

    console.log(isNaN(null)) // false

    console.log(isNaN(undefined)) // true

    isNaN的结果很大程度上取决于Number()类型转换,后面会专门有一部分来介绍。

    5.3 Number.isNaN(推荐使用)
        与isNaN()相比,Number.isNaN()不会自行将参数转换成数字,只有在参数是值为NaN的数字时,才会返回 true。

第6问:如何实现一个可靠的类型判断函数

    利用Object.prototype.toString.call([value]),可以精准判断数据类型,大家可以根据这个原理封装一个自己的type方法。

    toString.call(()=>{})       // [object Function]

    toString.call({})           // [object Object]

    toString.call([])           // [object Array]

    toString.call('')           // [object String]

    toString.call(22)           // [object Number]

    toString.call(undefined)    // [object undefined]

    toString.call(null)         // [object null]

    toString.call(new Date)     // [object Date]

    toString.call(Math)         // [object Math]

    toString.call(window)       // [object Window]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值