数据类型
一、类型
- Undefined
- Null
- Boolean
- String
- Number
- Symbol
- Object
- BigInt
undefined和null
undefined表示未定义,定义了变量为赋值默认为undefined
null表示空值,需要手动赋值为null
注意:
- 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有正负之分)
注意:
- 整数数值在15位及15位之下都能精确表示,16位往上会出现失真
- NaN==NaN //false Infinity===Infinity //true
- 非整数的 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