js梳理1-数据类型

222 阅读4分钟

1.js中的数据类型

  • js的数据类型分为:
    • 基本数据类型:Boolean、String、Number、Null、Undefined、Symbol、bigInt
    • 引用数据类型:Object、Array、Date、Function等。
  • 基本数据类型和引用类型的区别:
    • 内存中存储位置
      • 基本类型的数据是存储在栈中,占用的空间是固定,栈是先进后出的
      • 引用类型的数据存储在堆中,引用地址存在栈中,占用的空间是不固定的,堆是树形数据结构
    • 拷贝
      • 基本类型的数据,值的复制,互不影响
      • 引用数据的,赋值时仅改变引用的指针,指向同一对象互相影响;浅拷贝时只拷贝一层,第一层的基本类型互不影响,子对象会互相影响;深拷贝时会对子对象进行递归拷贝,拷贝前后的对象互相影响
    • 比较
      • 基本类型数据比较的值的比较

      • 引用数据类型引用地址的比较,判断是否指向同一个对象

2.js中的判断类型的方法

  1. typeof
    • 操作符返回一个字符串,表示未经计算的操作数的类型。
    • 基本类型除null返回object,其他类型能正确返回对应的类型字符串
    • 引用类型除了function返回function,其他类型返回object
    • typeof 可以判断一个变量是否声明,但是在let、const声明的变量之前调用typeof判断变量时会抛出referenceError。('变量' in window 或 window.hasOwnProperty('变量'))
    • typeof null 为object 的原因:是js的一个bug,不同对象在底层都表示成二进制,在javascript中二进制前三位表示类型,前三位都为0表示为object,而null的二进制全是0,前三位自然也为0,所以typeof null也是object。
  2. instanceof
    • instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链。
    • instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。Array.isArray()可以确认某个对象本身是否为 Array 类型。
  3. constructor
    • JavaScript 中的内置对象在内部构建时,JS引擎会为其添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向本身的引用。
    • null 和 undefined 不存在constructor
  4. toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为[object Xxx] ,其中 Xxx 就是对象的类型。对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息,以防toString方法被覆盖。
    • Object.prototype.toString.call(val)

3.js中类型实现一个获取类型的方法

  function getType(val){
    if (typeof val !== 'object') {
     
      return typeof val
    }
    
    let typeStr = Object.prototype.toString.call(val)
    
    return typeStr.replace(/(\[|object|\s|\])/g, '').toLowerCase()
  }

4.js中浮点精度丢失和大数危机

  • js中的数字
    • Number.MAX_SAFE_INTEGER 常量表示在 JavaScript 中最大的安全整数(maxinum safe integer)(2^53 - 1)。
    • Number.MIN_SAFE_INTEGER 代表在 JavaScript中最小的安全的integer型数字 (-(2^53 - 1)).
    • Number.MAX_VALUE 表示在 JavaScript 里所能表示的最大数值。
    • Number.MIN_VALUE JavaScript 中所能表示的最小的正值
    • Number.isSafeInteger()方法用来判断传入的参数值是否是一个“安全整数”(safe integer)
    • Number.EPSILON表示 1 与Number可表示的大于 1 的最小的浮点数之间的差值,可用于误差检查
  • 浮点数精度丢失 JavaScript 中所有数字包括整数和小数都使用一种类型 — Number。遵循 IEEE 754 标准,使用 64 位固定长度来表示,也就是标准的 double 双精度浮点数(32位为单精度浮点数)。
   0.1 + 0.2 // 0.30000000000000004
   0.55 * 100 // 55.00000000000001
   0.56 *100 // 56.00000000000001

在计算机表示小数:第一步:转换成二进制; 第二步:用二进制科学计算法表示; 第三步:表示成 IEEE 754 形式;但第一步和第三步都有可能  丢失精度

解决方案: 1.使用类似mathjs、decimal.js这样的库 
         2.扩大10n倍计算 再除以10n3.Number.EPSILONNumber.EPSILON的实质是一个可以接受的最小误差范围。
  • 大数危机
    • 大数处理精度丢失问题

      • 超出了最大安全数时精度丢失
        const num = 200000436035958034;
        console.log(num); // 200000436035958050
      
      • JSON.parse 转义时大数值会默认编码为 number 类型
    • 解决方案

      • 转字符串,前后端交互时,处理大数时,后端转化为字符串类型返回给前端
      • bigInt 新的类型,可以用来操作超出 Number 最大安全范围的整数,与JSON会冲突
      • 使用第三方库json-bigint、bignumber.js

5.Object

  • Object.defineProperty(obj, prop, descriptor)
    • enumerable
    • configurable
    • writable
    • get
    • set
  • proxy

总结:

参考资料:

细说 Javascript 中的浮点数精度丢失问题