0基础学前端「javascript 之 数据类型」

数据类型数量

  • js中数据类型一共8种,包含7种基本数据类型1种引用数据类型
    • 原始数据类型:null undefined string boolean number bigint symbol
    • 引用数据类型:object

存储方式

  • 原始数据类型的值存储在栈内存中,不可以被修改也没有任何方法可以调用,大小固定,占用空间比较小
  • 引用数据类型的指针存储在栈内存中,指针指向的值存储在堆内存中,大小不固定,一般占用空间比较大

原始数据类型为什么可以调用方法

  • 调用方法时js已经进行数据类型隐式转换了,会将原始数据类型转换为对应的包装类(Null,Undefined,Bigint等),包装类可以调用方法
  • 可以通过valueOf方法获取包装类的原始数据类型
  • 可以通过new Boolean(true) 方式获取原始数据类型的包装类

判断数据类型的方式

  1. typeof

    • typeof可以判断原始数据类型中的undefined symbol bigint string number boolean和函数function
    • typeof无法判断引用数据类型 结果都会返回object,由于原始数据类型null的存储地址和对象的地址相同所以也会返回object
  2. Object.prototype.toString.call

    • 可以判断所有的数据类型,返回格式为[object Number] 其中的Nubmer为对应的数据类型
  3. instanceof

    • 可以判断所有的引用数据类型,不能判断原始数据类型,因为原理是基于原型链
    • 原理:
      • 简单概括就是在构造函数的原型链中去寻找是否存在该对象的原型
      function myInstanceof (target, constructor) {
          const proto = Object.getPrototypeOf(target);
          let prototype = constructor.prototype;
          while (prototype) {
               if (proto === prototype) {
                      return true
               }
               prototype = Object.getPrototypeOf(prototype)
          }
          return false
      }
      
  4. constructor

    • 判断引用数据类型,原理是对象可以通过隐式原型对象上的constructor属性访问构造函数
    • 如果手动的改变了原型对象的指向,这种判断方式就不可以用了
  5. 通过隐式原型判断

    Object.getPrototypeOf([1,2,3]) === Array.prototype // true
    

判断数组的方式

  • instanceof
  • Object.prototype.toString.call
  • Array.isArray
  • Array.prototype.isPrototypeOf
  • Object.getPrototypeOf([1,2,3]) === Array.prototype

数据类型的转换

== 操作符 === 操作符 和Object.is()的区别

  • == 区别于 === 的地方在于,== 如果两边数据类型不同会进行隐式数据类型的转换,而全等则会直接返回false
  • Object.is和===主要有两点不同
    Object.is(+0,-0) //false
    Object.is(NaN,NaN) // true
    

数据类型转换规则

原始数据类型的转换规则

  • 数字和字符串

    • + 操作符会将数字转换为字符串进行字符串拼接
    • 其他运算会将字符串转为数字再运算,如果转换失败结果就是NaN
  • 数字和布尔

    • true转换为1 false转换为0
  • !运算符的转换

    • 假值会转为false 其他值都会转换为true
    • 假值包括(0,null,undefind,”,’false,NaN)

引用数据类型转为原始数据类型

  • 每一个对象都有一个toPrimitive方法 用来转换原始数据类型
    • 参数是个期望值,可以是number 或者是 string
    • 会根据期望值的类型依次调用valueOf或者toString方法,如果第一个方法返回的结果是原始数据类型则直接返回该值,否则继续调用第二个方法,如果仍然不是原始数据类型则会报错
    • 如果期望值是number则先调用valueOf方法 否则反之 一般只有Date的期望值是string其他的对象全是number
      const obj = {
    
            [Symbol.toPrimitive](primitive) {
                let typeArr = ['null', 'undefined', 'boolean', 'symbol', 'bigint', 'string', 'number']
                function myToString() {
                    return 'toString'
                }
                function myValueOf() {
                    return 'valueOf'
                }
    
                if (typeof primitive === 'string') {
                    let res = myToString()
                    if (typeArr.includes(typeof res)) {
                        return res
                    } else {
                        res = myValueOf()
                        if (typeArr.includes(typeof res)) {
                            return res
                        } else {
                            throw new TypeError('类型转换失败')
                        }
                    }
                } else {
                    let res = myValueOf()
                    if (typeArr.includes(typeof res)) {
                        return res
                    } else {
                        res = myToString()
                        if (typeArr.includes(typeof res)) {
                            return res
                        } else {
                            throw new TypeError('类型转换失败')
                        }
                    }
                }
    
            }
        }
    
        console.log(obj + 1) // toString1
    

BigInt

这个数据类型是es6新增的主要为了大数的计算,因为js中存在最大安全整数范围,Number.MAX_SAFE_INTEGER可以获取最大安全整数,超过这个范围计算的结果就会丢失精度,所以必须通过第三方库来解决这个问题,bigint的引入可以直接用原生js进行大数字的运算

一些面试题

  • null和undefined的区别

    • null是空对象,undefined是未定义的值,typeof null会返回object,undefined不是保留字所以需要使用void 0 这种方式安全的获取undefined的值
  • 0.1 + 0.2 === 0.3 为什么是false

    • 因为js中存储数字的方式是通过IEEE754标准双精度浮点数,浮点数之间的运算会存在精度丢失的问题,所以不相等,
    • 解决方案:
      • 可以通过将左边的数转为整数再将结果转为小数
      • 通过Number.EPLISON,这个数极小,只要两边结果之差小于这个数就认为相等
      • 通过四舍五入
  • isNaN 和 Number.isNaN区别

    • isNaN是Object的方法,如果值不是数字会进行数据类型转换再判断
    • Number.isNaN会先判断数据类型,如果是数字并且值是NaN才会返回true

原文链接:https://juejin.cn/post/7255559160820334650 作者:芷茵

(0)
上一篇 2023年7月15日 上午10:26
下一篇 2023年7月15日 上午10:36

相关推荐

发表回复

登录后才能评论