js从入门到精通系列(一)数据类型

109 阅读5分钟

数据类型在js中是很重要的一部分,是必须掌握的基础中的基础,一定要掌握,面试中也是必考的内容之一。

一. 数据类型基础

数据类型有哪些

原始数据类型(又叫基本数据类型)

  • string
  • number
  • null
  • undefined
  • boolean
  • symbol
  • bigint

引用数据类型

  • object

判断数据类型的方法

判断基本数据类型:

  • typeof
    // 可以判断除了null以外的所有原始数据类型
    typeof 1 //number  

判断引用数据类型: 常见的五种

  1. Object.prototype.toString.call(obj)
    //通过Object的原型方法toString可以判断出数据类型
    const type = Object.prototype.toString.call([]) // [object Array]
    type.slice(8, -1) // 'Array'
    
  2. Object.prototype.isPrototypeOf(obj)
    // 判断调用者是否在原型链上
    RegExp.prototype.isPrototypeOf(/test/) // true
    Array.prototype.isPrototypeOf(/test/) // false
    
  3. instanceof
    • instanceof的原理是判断原型链上是否存在构造函数
    // 只要在原型链上就会返回true
    1 instanceof Array //false
    [] instanceof Array //true
    [] isntanceof Object //true
    
  4. obj.getPrototypeOf()
    • 原理是判断调用者是否在实例对象的原型链上
      Array.prototpye.isPrototypeOf([]) // true
      Object.prototpye.isPrototypeOf([]) // true
      Function.prototpye.isPrototypeOf([]) // false
    
  5. constructor
    • 原理是对象可以通过constructor访问其构造函数来判断数据类型
    • 注意:如果创建一个对象改变了这个对象的原型,这个就不生效了,慎用
    //
    const per = {a:1,b:2}
    per.constructor === Object // true
    // 改变实例隐式原型的指向
    per.__proto__ = new Array()
    per.constructor === Object // false
    

判断数组:

  • Array.isArray([])
  • 上面的五种判断引用数据类型的方法都适用数组

数据类型的区别

存储位置

  • 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
  • `引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
  • 关于堆栈的概念就不在本章中讲了,可以移步数据结构

包装类

基本数据类型是没有自己的属性的,所以正常是不能像对象一样去通过.的方式使用自己的方法和属性的,那为什么可以'abc'.length的呢,原来每个数据类型都有对应的包装类我们使用包装类的属性时js引擎会自动将基本数据类型转换为包装类,所以原始数据类型可以调用属性

二.类型转换

强制类型转换

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

  • Object.valueOf

基本数据类型之间的转换

  • 可以通过对应的包装类构造函数去转换
    const a = 1
    String(a)//转字符串
    Number(a)//转数字
    Symbol(a)//转smyobl
    Boolean(a)//转布尔
    toString(a)//转字符串
    Bigint(a) //转bigint
    

隐式数据类型转换(重点

== 操作符的转换规则

  1. 如果类型相同,调用 === 操作符

  2. 如果类型不同,尝试类型转换

  3. 查看是否是 undefinednull 比较

  • ✅ 返回 true
  • ⬇️ 如果不是继续下一条规则
  1. 是否在比较 stringnumber
  • ✅ 如果是,那么将 string 转为 number 并回到最初重新比较 ♻️
  • ⬇️ 如果不是继续下一条规则
  1. 查看我们比较的项中是否有 boolean
  • ✅ 如果有,那么将 boolean 转为 number 并回到最初重新比较 ♻️
  • ⬇️ 如果不是继续下一条规则
  1. 查看是否有一项是 object
  • ✅ 如果有,那么将 object 转为其原始值 primitive 并回到最初重新比较 ♻️

  • ❌ 如果还不是,只能返回 false 了💩

引用数据类型转换原始数据类型规则

我们需要知道转换类型的这个方法在 JS 源代码中是 ToPrimitive 这个方法,该方法有一个可选参数 PreferredType,这个参数的作用是指定期望类型;如果第一个参数对应的对象可以被转换为不止一种类型,那么后者可以作为一种暗示,表示该对象应该转换为那种类型

  1. 默认情况下(期望类型默认为 number

    1. 调用 valueOf 方法:

      • ✅ 如果返回的是原始值,那么就用这个
      • ⬇️ 如果返回的不是原始值,那么跳到下一步
    2. 调用 toString 方法:

      • ✅ 如果返回的是原始值,那么就用这个
      • ❌ 否则报错💩
  2. 如果期望类型为 string

    1. 调用 toString 方法:

      • ✅ 如果返回的是原始值,那么就用这个
      • ⬇️ 如果返回的不是原始值,那么跳到下一步
    2. 调用 valueOf 方法:

      • ✅ 如果返回的是原始值,那么就用这个
      • ❌ 否则报错💩
  3. 如果对象是 Date 类型(期望类型为 string):

    1. 调用 toString 方法:

      • ✅ 如果返回的是原始值,那么就用这个
      • ⬇️ 如果返回的不是原始值,那么跳到下一步
    2. 调用 valueOf 方法:

      • ✅ 如果返回的是原始值,那么就用这个
      • ❌ 否则报错💩

简单的说就是默认调用 valueOf 方法,然后是 toString 方法;如果对象是 Date 类型或对象的期望类型为 string,那么先调用 toString 方法

基本数据类型之间的转换规则

转换为 number

  1. undefined 👉 NaN 如果是 undefined 则直接转换成 NaN
  2. null 👉 0 如果是 null 则转换成 0
  3. boolean 👉 0/1 如果是 boolean 则转换成 0 或 1
  4. string 👉 0/NaN/(parse to number) 如果是 string 则转换成对应的 number,空字符串转换为 0,无法转换的则为 NaN
  5. object 👉 首先获取原始值然后再转为 number

转换为 string

  1. undefined 👉 'undefined'
  2. null 👉 'null'
  3. number 👉 'number
  4. boolean 👉 'true'/'false'
  5. object 👉 首先获取原始值,然后转为 string

转为 boolean

  1. undefined 👉 falsy