值类型
- 原始值类型
- number 数字
- string 字符串
- boolean 布尔
- null 空对象指针
- undefined 未定义
- symbol 唯一值
- bgint 大数(es8)
- 引用类型
- 普通 object
- 标准特殊对象Array、RegExp、Date、Math、Error...
- 非标准特殊对象 Number、String、Boolean...
- 调用执行对象 Function
number 类型
- 1 0 -1 NaN(不是一个数的数据类型)
- Infinity 正无穷 -Infinity负无穷
- NaN === NaN -> false
- Object.is(NaN, NaN) -> true
- 最大安全数 Number.MAX_SAFE_INTEGER 9007199254740991,超过这个数字进行运算,运算的结果不一定准确了
// => 错误写法
if(num === NaN) {...}
// => 适合写法
if(Object.is(num, NaN)) {...}
//测一个值是否为有效数字
// -> 不是数字会隐式转换为 number类型再去检测
if(isNaN(num)) {...}
如何处理大数
- 先转为 BigInt 类型 BigInt(val) -> bv
- 基于bv 进行运算(运算的值也必须是 BigInt 的值)
- 把运算的结果转为字符串(去掉n)
let a = Number.MAX_SAFE_INTEGER;
let b = BigInt(a)
let c = b + 10n
console.log(c.toString())// 9007199254741001
string 类型
- '' "" ``
boolean 类型
- true false
symbol 唯一值
console.log(Symbol() === Symbol()) // false
console.log(Symbol('asd') === Symbol('asd')) // false
- 作用1. 给对象设置唯一值类型的属性(对象属性名的类型:string, symbol)
const b = 'dd'
const sym = Symbol('cc')
const obj = {
a: '123',
name: 'mm',
0: 2,
[b]: 'zz',
[Symbol('asd')]: 400,
[sym]: 500
}
console.log(obj['name'])// mm
console.log(obj.a)// 123
console.log(obj[0]) // 2
console.log(obj[b])// zz
console.log(obj[Symbol('asd')])// undefined
console.log(obj[sym])// 500
- for in 循环获取不到 symbol类型的属性
- Object.keys() 获取当前对象所有非symbol类型的私有属性,返回一个包含属性名数组
- Object.getOwnPropertySymbol() 获取symbol类型私有的属性
// => 获取所有的私有属性
const obj = {
a: '123',
name: 'mm',
[Symbol('asd')]: 400
}
let keys = Object.keys(obj)
keys = keys.concat(Object.getOwnPropertySymbol(obj))
- Reflect.ownKeys() 获取所有的私有属性,无论什么类型(等效上面的写法)
- 作用2: 把Symbol作为对象,提供的很多静态的属性方法,是JS很多知识的底层原理
- 作用3: vuex、redux中我们需要派发多个行为标识、可把这些标识统一管理,保证标识的唯一性
Symbol.toPrimitive/hasInstance/toStringTag/iterator/asyncIterator...
数据类型检测的方式
Object.prototype.toString.call([value]) [value] instanceof [Constructor] [value].constructor
typeof 数据类型检测机制
typeof [value] 返回值 是字符串,字符串中包含着乐星 typeof null -> 'object' typeof 检测对象类型,除函数'function',其余都是'object'(不能细分对象)
为什么会这样尼?
-
- JS中创建的所有类型值,在计算机中都是按照"二进制"的形式进行存储
-
- typeof检测也是根据二进制值进行检测的,其中有一条规则:
- 如果是已'000'开始的二进制,则被识别为对象(null存储的二进制都是0,符合000开始);然后再去看对象是否实现了(call方法)
- 实现call就是函数,没实现就是function
- 3.typeof 检测一个未声明的变量,不会报错,结果是'undefined'
typeof 12 // 'number'
typeof 'ass' // 'string'
typeof null // 'object'
typeof true // 'boolean'
typeof undefined // 'undefined'
typeof Symbol() // 'symbol'
typeof 10n // 'bigint'
typeof {} // 'object'
typeof [] // 'object'
typeof /^&/ // 'object'
typeof function() {} // 'function'
检测是否未对象
if (val !== null && (typeof val === 'object' || typeof val === 'function')) {}
if (val !== null && /^(object|function)$/i.test(typeof val)) {}
判断一个对象是否为纯对象
- 对象.proto === Object.prototype