数据类型

180 阅读2分钟

数据类型

一、类型

  1. Undefined
  2. Null
  3. Boolean
  4. String
  5. Number
  6. Symbol
  7. Object
  8. BigInt

undefined和null

undefined表示未定义,定义了变量为赋值默认为undefined

null表示空值,需要手动赋值为null

注意:

  1. undefined不是一个关键字,可以作为一个变量来使用。所以常常看到用void 0来代替undefined。(语言缺陷)
const fn=()=>{
  let undefined=1
  console.log(undefined)  //1
}

2.typeof null 返回object null解释为object值的空引用(强行解释?)

typeof undefined //undefined
typeof null //object

Boolean

true/false

一些特殊值:

undefined/null/0/NaN/'' 表示false

数字1 表示true

0==false //true
1==true //true

Number

一些特殊值:

NaN,Infinity,-Infinity,0,-0 (0有正负之分)

注意:

  1. 整数数值在15位及15位之下都能精确表示,16位往上会出现失真
  2. NaN==NaN //false Infinity===Infinity //true
  3. 非整数的 Number无法用==来比较 (浮点数运算的精度问题),可以用JavaScript 提供的最小精度值辅助比较
0.1 + 0.2 == 0.3 //false
Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON   //true

BigInt

新的数字类型,可以用任意精度表示整数

Symbol

Symbol 生成一个全局唯一的值

注意:Symbol 生成值时,但是即使描述相同,值也不相等

Symbol()==Symbol()   //false
Symbol("symbol")==Symbol("symbol")   //false

Object

引用类型,存放在堆内存中

和基本类型相似的对象 Number String Boolean

Number、String 和 Boolean,这三个构造器是两用的,当跟 new 搭配时,它们产生对象,当直接调用时,它们表示强制类型转换。

let a=Number(1)   // 1   number类型
let b=new Number(1) // Number {1}   //object类型

二、数据类型判断

typeof

typeof能判断number、boolean、string、symbol、object、undefined、function 但是不能判断null和具体的object对象(array、date等)

typeof 1    //number
typeof true //boolean
typeof ''  //string
typeof Symbol() //symbol
typeof {} //object
typeof undefined //undefined
typeof new Function() //function
typeof null //object
typeof [] //object
typeof new Date() //object

instanceof

a instanceof b,判断a是否为b的实例,是一个运算符返回boolean

注意:instanceof 检测的是原型,只能用来判断两个对象是否属于实例关系

[] instanceof Array //true 
[] instanceof Object //true

Object.prototype.toString.call()

Object原型上的toString方法能返回当前对象的类型,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。

由于大部分对象的toString方法被重写了,就需要用call来调用。Reflect.apply()亦可

({}).toString()  //[object Object]
({toString(){return '111'}}).toString()  //111
Object.prototype.toString.call({toString(){return '111'}})  //[object Object]

[].toString()  // ''
Object.prototype.toString.call([])  // [object Array]

对于基本数据类型,若不为 null 或 undefined,则将参数转为对象(装箱)

Object.prototype.toString.call(null)  //[object Null]
Object.prototype.toString.call(undefined) //[object Undefined]
Object.prototype.toString.call(1) //[object Number]
Object.prototype.toString.call(new Number(1)) //[object Number]

三、类型转化

基本数据类型转对象——装箱

每一种基本类型在对象中都有对应的类,装箱就是把基本类型转换为对应的对象。

基本类型不是对象本身没有方法,但是由于装箱操作基本类型能使用对用对象的方法

'a'.slice() // 'a'
String.prototype.slice=()=>{return 'new slice'}
'a'.slice() // 'new slice'

对象转基本数据类型——拆箱

拆箱会调用 valueOf 和 toString 来获得对用类型的值。如果 valueOf 和 toString 都不存在,或者没有返回基本类型,就是报错

对于显示的字符串转化String(obj) toString的优先级大于valueOf,其余情况下valueOf优先级大于toString

无论先调用toString还是valueOf 只要返回了基本类型就不会在执行另一个方法

  let obj={
            valueOf : () => {console.log("valueOf"); return 1}, 
            toString : () => {console.log("toString"); return 2},
        }
  console.log( obj+0)   // valueOf 1

   let obj={
            valueOf : () => {console.log("valueOf"); return '1'}, 
            toString : () => {console.log("toString"); return 2},
        }
  console.log( obj+0)   // valueOf '10'

  let obj={
            valueOf : () => {console.log("valueOf"); return {}}, 
            toString : () => {console.log("toString"); return 2},
        }
  console.log( obj+0)   // valueOf  toString 2

 let obj={
            valueOf : () => {console.log("valueOf"); return {}}, 
            toString : () => {console.log("toString"); return {}},
        }
  console.log( obj+0)   // valueOf  toString 报错

  let obj={
            valueOf : () => {console.log("valueOf"); return {}}, 
            toString : () => {console.log("toString"); return {}},
        }
  console.log( String(obj)) //toString valueOf 报错

实际上拆箱先调用的是拆箱是首先调用的是Symbol.toPrimitive对应的函数,然后由此函数决定先调用valueOf还是toString。

Symbol.toPrimitive是一个内置的 Symbol 值,它是作为对象的函数值属性存在的,当一个对象转换为对应的原始值时,会调用此函数——MDN

  let obj={
            valueOf : () => {console.log("valueOf"); return {}}, 
            toString : () => {console.log("toString"); return {}},
            [Symbol.toPrimitive]:(type) => {
              console.log("toPrimitive",type)
                if(type==="string")  {//xxxxx} 
                if(type==="number")  {//xxxxx} 
                // xxxxxxx
            },
        }
      
      String(obj) // string
			Number(obj) // number
			+obj // default

Symbol.toPrimitive有一个参数标识类型 默认default行为与number一致先调用valueOf 如果是string则先调用toString

我们可以重写Symbol.toPrimitive对应函数

 let obj={
           	haha:()=>{return 'haha'},
            [Symbol.toPrimitive]:(type) => {console.log("toPrimitive"); return obj.haha()},
        }
     
  console.log(obj+'') // toPrimitive haha