数据类型、类型判断、类型转换
JS 的数据类型对我来说一直是一个坑,知识点如果只是背,迟早有一天会忘。所以打算写一篇博客,刨根问底,把它嚼烂了,相信便不会轻易忘记了。
PS:写完最后一块,我后脑勺一涨一涨的。
数据类型
基本类型
基本类型(基本数值、基本数据类型)是一种既非对象也无方法的数据。
共有6种基本类型: number
,string
, boolean
, null
, undefined
, symbol
(ECMAScript 2015新增)。
所有基本类型的值都是不可改变的。但需要注意的是,基本类型本身和一个赋值为基本类型的变量的区别。变量会被赋予一个新值,而原值不能像数组、对象以及函数那样被改变。
Number
根据 ECMAScript 标准,JavaScript 中只有一种数字类型:基于 IEEE 754 标准的双精度 64 位二进制格式的值(-(263 -1) 到 263 -1)。它并没有为整数给出一种特定的类型。除了能够表示浮点数外,还有一些带符号的值:
+Infinity
-Infinity
NaN
String
JavaScript的字符串类型用于表示文本数据。它是一组16位的无符号整数值的“元素”。在字符串中的每个元素占据了字符串的位置。第一个元素的索引为0,下一个是索引1,依此类推。字符串的长度是它的元素的数量。
Boolean
布尔表示一个逻辑实体,可以有两个值:true
和 false
。
Null
Null 类型只有一个值: null,null表示”没有对象”,即该处不应该有值。
Undefined
一个没有被赋值的变量会有个默认值 undefined,undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义。
Symbol
符号(Symbols)是ECMAScript 第6版新定义的。符号类型是唯一的并且是不可修改的, 并且也可以用来作为Object的key的值. 在某些语言当中也有类似的原子类型(Atoms). 你也可以认为为它们是C里面的枚举类型.
引用类型(对象)
引用类型内存放的并非具体的值,而是所对应对象的内存地址。
常用的有引用类型有:Object
、Array
、Date
、RegExp
、Function
等
Object
一个 Javascript 对象就是键和值之间的映射。键是一个字符串(或者 Symbol
) ,值可以是任意类型的值。
Array
数组是一种使用整数作为键( integer-key-ed )属性和长度( length )属性之间关联的常规对象。此外,数组对象还继承了 Array.prototype 的一些操作数组的便捷方法。
Date
用于存放日期时间的内建对象。
RegExp
用于正则表达式的对象。
Function
函数是一个附带可被调用功能的常规对象。
类型判断
typeof
typeof
操作符返回一个字符串,表示未经计算的操作数的类型。
类型 | 结果 |
---|---|
Number | “number” |
String | “string” |
Boolean | “boolean” |
Null | “object” |
Undefined | “undefined” |
Symbol | “symbol” |
Function | “function” |
其他引用类型 | “object” |
Null 返回 “object”
在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null的类型标签也成为了 0,typeof null就错误的返回了”object”。
New 操作符
1 | typeof new Boolean(true) === 'object'; |
instanceof
instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置,适合用于判断自定义的类实例对象, 而不是用来判断原生的数据类型。
1 | function Car(make, model, year) { |
Object.prototype.toString
Object.prototype.toString 之所以能实现类型识别,是因为它可以直接获取 this 的 [[class]]
。
ES5 里如此介绍它的运行过程:
- 如果 this 的值是 undefined, 返回 “[object Undefined]”.
- 如果 this 的值是 null, 返回 “[object Null]”.
- 令 O 为以 this 作为参数调用 ToObject 的结果 .
- 令 class 为 O 的 [[Class]] 内部属性的值 .
- 返回三个字符串 “[object “, class, and “]” 连起来的字符串 .
因此我们只需要使用 call / apply 将需要判断的变量绑定到 toString 上的 this 即可。
1 | Object.prototype.toString.call(null) // [object Null] |
类型转换
常用类型互相转换参考
基本类型 -> 布尔类型
类型 | 值 | 结果 |
---|---|---|
Number | 0、-0、NaN | false |
其他 | true | |
String | “” | false |
其他 | true | |
Null | Null | false |
Undefined | Undefined | false |
Symbol | / | true |
基本类型 -> 字符串类型
类型 | 值 | 结果 |
---|---|---|
Number | / | 值 + “” |
Boolean | ||
Null | ||
Undefined | ||
Symbol | / | Uncaught TypeError |
基本类型 -> 数值类型
类型 | 值 | 结果 |
---|---|---|
String | 数值字符串 且 只有前后有空格 | 正常数值 |
其他(包括:数值字符串,但中间数值中间有空格) | NaN | |
Boolean | true | 1 |
false | 0 | |
Null | Null | 0 |
Undefined | Undefined | NaN |
Symbol | / | Uncaught TypeError |
基本类型 -> 对象类型
类型 | 值 | 结果 |
---|---|---|
Number | / | 对应构造函数生成的对象 |
String | ||
Boolean | ||
Symbol | ||
Null | {} | |
Undefined |
对象类型 -> 基本类型
值 | 类型 | 结果 |
---|---|---|
/ | Number | NaN |
String | [object Object] | |
Boolean | true | |
Symbol | Symbol([object Object]) |
数组类型 -> 字符串类型
1 | String([1,2,3]) // "1,2,3" |
== 的类型转换
1 | null == undefined // true |
+ 的类型转换
1 | 91 + "1" // "911" 两边有值,且只要有一个非数值型,则视为字符串连接符。 |
其他数学运算符 的类型转换
1 | // 没有任何余地,全**给我转成数值进行运算 |
! 的类型转换
1 | // 值转成布尔型进行运算 |