JS 中一个变量可以存放两种类型的值:基本类型和引用类型。
JS 数据类型有 7 种(ES6 新增一种 Symbol):
基本类型(原始类型):
BooleanNullUndefinedNumberStringSymbol(ECMAScript6 新定义),符号类型是唯一的并且是不可修改的
引用类型(复杂类型):
Object
基本类型
基本类型的值是按值访问
基本类型的值是不可变的
1 | var str = '123hello321' |
基本类型的比较是它们的值的比较
不同类型之间也可以比较,因为做了隐式转换。涉及隐式转换最多的两个运算符 + 和 ==。
隐式转换中主要涉及到三种转换:
- 将值转为原始值,
ToPrimitive()。 - 将值转为数字,
ToNumber()。 - 将值转为字符串,
ToString()。
通过 ToPrimitive 将值转换为原始值
ToPrimitive(input, PreferredType?)
input 是要转换的值,PreferredType 是可选参数,可以是 Number 或 String 类型。他只是一个转换标志,转化后的结果并不一定是这个参数所值的类型,但是转换结果一定是一个原始值(或者报错)。
如果 PreferredType 被标记为 Number,那么先是调用 valueOf 方法,如果返回值是原始值则结束;否则重新调用 toString 方法,如果是原始值则结束,不然就会抛出 TypeError 异常。
如果 PreferredType 被标记为 String,那么先是调用 toString 方法,如果返回值是原始值则结束;否则重新调用 valueOf 方法,如果是原始值则结束,不然就会抛出 TypeError 异常。(两者相反)
valueOf():返回最适合该对象类型的原始值;toString(): 将该对象的原始值以字符串形式返回。
没有
PrefferedType时,按照下面规则:如果该对象为Date类型,则PreferredType被设置为String;否则,PreferredType被设置为Number。
通过 ToNumber 将值转换为数字
| 参数 | 结果 |
|---|---|
| undefined | NaN |
| null | +0 |
| 布尔值 | true 转为 1,false 转为 |
| 字符串 | 能解析则变为数字,否则 NaN |
| 对象 | 先 ToPrimitive(input, Number),再 ToNumber |
通过 ToString 将值转换为字符串
| 参数 | 结果 |
|---|---|
| undefined | ‘undefined’ |
| null | ‘null’ |
| 布尔值 | true 转为 ‘true’,false 转为 ‘false’ |
| 数字 | 直接转,NaN 变为 ‘NaN’ |
| 对象 | 先 ToPrimitive(input, String),再 ToString |
举例:
1 | console.log({} + {}) //"[object Object][object Object]" |
1 | console.log(2 * {}) //NaN |
== 运算符时隐式转换规则
- x,y 为
null、undefined两者中一个 // 返回 true - x、y 为
Number和String类型时,则转换为Number类型比较。 - 有
Boolean类型时,Boolean转化为Number类型比较。 - 一个
Object类型,一个String或Number类型,将Object类型进行原始转换后,按上面流程进行原始值比较。
1 | const a = { |
基本类型的变量是存放在栈内存(Stack)里的
1 | var a, b |
栈内存中包括了变量的标识符和变量的值。

引用类型
除了 6 种基本数据类型外,还要剩下的引用类型,即 Object 类型。细分的话,有:Object 类型、Array 类型、Date 类型、RegExp 类型、Function 类型 等。
引用类型的值是按引用访问的。
- 引用类型的值是可变的
1 | var obj = { name: 'zyj' } // 创建一个对象 |
- 引用类型的比较是引用的比较
1 | var obj1 = {} // 新建一个空对象 obj1 |
- 引用类型的值是保存在堆内存(
Heap)中的对象(Object)
与其他编程语言不同,JavaScript 不能直接操作对象的内存空间(堆内存)。
1 | var a = { name: 'percy' } |