一、数据类型
1. 基本数据类型
- string
- number:NAN「不是一个有效数字」、Infinity「无穷大的值」
检测是否为有效数字:
isNAN([value])不论
[value]啥类型,默认隐式转换为数字类型Number([value]),再校验是否为有效数字,如果是有效数字返回false,不是有效数字返回true。
-
Boolean
-
undefined
-
null
-
symbol (唯一值,ES6新增)
1)给对象设置唯一值属性
let key = Symbol() let obj = { [key]:100 } console.log(obj[key]) // 获取当前对象所有symbol类型的私有属性 Object.getOwnPropertySymbols(obj) // 获取对象所有非Symbol属性 Object.keys(obj)2)Symbol 方法
Symbol.hasInstance, Symbol.toStringTag, Symbol.toPrimitive
-
bigInt :大数
最大安全数字:9007199254740991,超过这个数字进行运算就不准确了 Number.MAX_SAFE_INTEGER 最小安全数字:-9007199254740991 Number.MIN_SAFE_INTEGER服务端有longInt长整型,如果传给客户端,客户端无法有效处理,就需要用到bigInt处理
let num = BigInt('9007199254740991') + 1n // 得到9007199254740992n 服务器不支持bigInt,转为字符串即可 let newNum = num.toString()
2. 引用数据类型(对象类型)
-
标准普通对象:object
-
标准特殊对象:Array/RegExp/Date/Error/Math/ArrayBuffer/DataView/Set/Map...
-
非标准特殊对象:Number/String/Boolean/Symbol/BigIng...
1. 字面量方式创建出来的是原始值 let a = 10 2. 构造函数/Object 方式创建出来的是对象值 let b = new Number(10) let c = Object(10) 总结:基于构造函数「或者Object」创建出来的原始值对象类型的格式信息,类型属于对象类型.Symbol和BigInt不能用构造函数方式创建,会报错。 可以使用Object()方式. -
函数对象,可调用对象「实现了call方法」:function
- 属于特殊的对象,它拥有很多函数的概念,对象只是它的附属。
- 每一个函数的原型链直接指向Function的原型(
__proto__=>Function.prototype),所以直属类型是函数,所以函数类型应该是一个单独的分类。
二、数据类型检测
1. typeof 检测数据类型的逻辑运算符
1)返回的结果是一个字符串,包含了对应的数据类型
typeof typeof typeof 12 => 'string'
2) 弊端:
-
typeof null => "object"
typeof 认为存储的二进制中前几位都是0的为object,null存储的结果是000000,返回“object”。但可以理解为这是一个bug,null依然是基本数据类型。
-
typeof 不能细分对象类型(除函数对象返回‘function’,其余返回都是“object”)
-
检测一个未被声明的变量不会报错,返回‘undefined’
3) 底层处理机制
- 所有的数据类型值,在计算机底层都是按照“二进制”来存储的「64位」
- typeof是按照二进制值来检测:前三位是000的,都被认为是对象。如果对象内部实现了[[call]]方法,则认为是函数。
- typeof处理性能相对好一些
2. instanceof 检测是否为某个类的实例
let n1 = 10 // Number类的一个实例「原始值」
let n2 = new Number(10) // Number类的一个实例「对象」
// 数字类型为什么可以调方法?内部处理机制“装箱和拆箱”:10->Object(10)「对象实例」
console.log(n1.toFixed(2)) // 10.00
console.log(n2.toFixed(2)) // 10.00
console.log(n1 + 10) // 20
console.log(n2 + 10) // 20 n2对象先找Symbol.toPrimitive,没有再找valueof「原始值」
console.log(n1 intanceof Number) // false instanceof有缺陷,不能识别原始值
console.log(n2 intanceof Number) // true
3. constructor 检测构造函数
4. Object.prototype.toString.call([value]) 检测数据类型
---------------工具类检测方法---------------
5. Array.isArray([value]) 检测是否为数组
6. isNAN 检测是否是一个有效数字
三、特殊数据类型分析
1. Number
-
NAN(not a number)不是一个有效数字
NAN是特殊的数字类型,
console.log(typeof NAN) // "number"判断一个值是否是NAN,使用isNAN方法,返回值为false,则值为数字类型。
isNAN(0) // false isNAN('A') //true其中涉及一个隐式转换,利用Number()方法判断值能否能否转为一个数字,如果不能返回则为NAN。
-
Infiniti/-Infinity: 正无穷大/负无穷大,也属于数字类型。
2. object 普通对象
对象的属性名一定不能是引用类型值,默认会把引用类型值转换为字符串进行处理(toString()方法,转换为:“[object object]”)。属性名可以是数字,布尔值,字符串。
3. 数组
数组是特殊的对象,区别是数组的属性名是有规律的逐渐递增的代表位置的数字索引。
四、数据类型转换规则
1. 把其他类型「原始值」转换为对象
Object([value])
2. 其他类型转为布尔
规则:只有“0,NAN,undefined,null,‘’「空字符串」”会变为false,其余都转为true
转换方法:
- Boolean([value])
- !![value]
- ![value] 转换为布尔类型取反
- 条件判断:if(1){}
- A || B 或 A && B 举例: console.log(!![]) => true console.log(!!-1) => true
3. 其他类型转为字符串
规则:原始值转换直接用引号包起来;bigInt会去除n。
转换方法:
-
toString() 「排除Object.prototype.toString(),因为是检测数据类型的」
-
字符串/模版字符串拼接 「“+”在js中除了数学运算,还有字符串拼接功能」
“+”左右两边,有一边出现字符串或者部分对象,都是按照字符串拼接处理的
let n = 10 {}+n => 10 // 把左侧的{}当作代码块,不参与运算,运算的只有+n n+{} // '10[objec object]' 字符串拼接不是所有对象都是字符串拼接,规则如下:
- 先去调对象的
Symbol.toPrimitive属性值,如果没有这个属性 - 再去调对象的
valueOf获取原始值,如果不是原始值 - 再去调对象的
toString()转换为字符串。「如果是想转换为数字,则还会调用Number处理」
例1: 10 + [10,20] => 1010,20 10 + new Number(10) => 20 //new Number(10).valueOf()有原始值 例2: let obj = {x:10} 10 + obj = “10[object object]” // obj[Symbol.toPrimitive] -> undefined // obj.valueOf() -> {x:10} // obj.toString() -> "[object object]" 例3: 改写上条示例,让结果变为20 let obj = { x:10, // 重写属性 [Symbol.toPrimitive](hint){ console.log(hint) // "default","string","number" return this.x } } 10 + obj = 20 // hint值是由浏览器,根据词法解析来识别的。 - 先去调对象的
4. 其他类型转为数字
- Number([value])
- 一般用于隐式转换
- 字符串 -> 数字 「空字符串变为0,字符串中出现非有效数字字符结果为NAN」
- 布尔 -> true-1,false-0
- null -> 0
- undefined -> NAN
- symbol -> 报错
- bigInt -> 正常转换
- 对象遵循 Symbol.toPrimitive/valueOf/toString/Number
- parseInt/parseFloat([value])
-
首先会把[value]变为字符串,从字符串左侧第一个字符开始查找,直到找到一个非有效数字字符为止,把找到的结果转换为数字,一个都没找到,结果就是NAN。「parseFloat多识别一个小数点」
-