JavaScript中的数据类型有哪些?
1 前⾔
在 JavaScript 中,我们可以分成两种类型:
两种类型的区别是:存储位置不同
2 基本类型
基本类型主要为以下6种:
- Number
- String
- Boolean
- Undefined
- null
- symbol
- bigint
2.1 Number
数值最常⻅的整数类型格式则为⼗进制,还可以设置⼋进制(零开头)、⼗六进制(0x开头)
let intNum = 55 // 10进制的55
let num1 = 070 // 8进制的56
let hexNum1 = 0xA //16进制的10
浮点类型则在数值汇总必须包含⼩数点,还可通过科学计数法表⽰
let floatNum1 = 1.1;
let floatNum2 = 0.1;
let floatNum3 = .1; // 有效,但不推荐
let floatNum = 3.125e7; // 等于 31250000
在数值类型中,存在⼀个特殊数值 NaN ,意为“不是数值”,⽤于表⽰本来要返回数值的操作失败了(⽽不是抛出错误)
console.log(0/0); // NaN
console.log(-0/+0); // NaN
2.2 Undefined
Undefined 类型只有⼀个值,就是特殊值 undefined 。当使⽤ var 或 let 声明了变量但没有初始化时,就相当于给变量赋予了 undefined 值
let message;
console.log(message == undefined); // true
包含 undefined 值的变量跟未定义变量是有区别的
let message; // 这个变量被声明了,只是值为 undefined
console.log(message); // "undefined"
console.log(age); // 没有声明过这个变量,报错
2.3 String
字符串可以使⽤双引号(")、单引号(')或反引号(`)标⽰
let firstName = "John";
let lastName = 'Jacob';
let lastName = Jingleheimerschmidt
字符串是不可变的,意思是⼀旦创建,它们的值就不能变了
let lang = "Java";
lang = lang + "Script"; // 先销毁再创建
2.4 Null
Null 类型同样只有⼀个值,即特殊值 null
逻辑上讲, null 值表⽰⼀个空对象指针,这也是给 typeof 传⼀个 null 会返回 "object" 的原因
let car = null;
console.log(typeof car); // "object"
undefined 值是由 null 值派⽣⽽来
console.log(null == undefined); // true
只要变量要保存对象,⽽当时⼜没有那个对象可保存,就可⽤ null 来填充该变量
2.5 Boolean
Boolean (布尔值)类型有两个字⾯值: true 和 false
通过 Boolean 可以将其他类型的数据转化成布尔值
规则如下:
数据类型 |
转换为false |
转换为true |
String |
'' |
非空字符串 |
Number |
0/NaN |
⾮零数值(包括⽆穷值) |
Object |
null |
任意对象 |
Undefined |
undefined |
N/A(不存在) |
2.6 Symbol
Symbol (符号)是原始值,且符号实例是唯⼀、不可变的。符号的⽤途是确保对象属性使⽤唯⼀标识符,不会发⽣属性冲突的危险
let genericSymbol = Symbol();
let otherGenericSymbol = Symbol();
console.log(genericSymbol == otherGenericSymbol); // false
let fooSymbol = Symbol('foo');
let otherFooSymbol = Symbol('foo');
console.log(fooSymbol == otherFooSymbol); // false
2.7 BigInt
BigInt(ES6引入): 大整数类型,用来安全地存储和操作大于 2^53 - 1(Number.MAX_SAFE_INTEGER)的大整数
3 引⽤类型
复杂类型统称为 Object ,我们这⾥主要讲述下⾯三种:
3.1 Object
创建 object 常⽤⽅式为对象字⾯量表⽰法,属性名可以是字符串或数值
let person = {
name: "Nicholas",
"age": 29,
5: true
};
3.2 Array
JavaScript 数组是⼀组有序的数据,但跟其他语⾔不同的是,数组中每个槽位可以存储任意类型的数据。并且,数组也是动态⼤⼩的,会随着数据添加⽽⾃动增⻓
let colors = ["red", 2, {age: 20 }]
colors.push(2)
3.3 Function
函数实际上是对象,每个函数都是 Function 类型的实例,⽽ Function 也有属性和⽅法,跟其他引⽤类型⼀样
函数存在三种常⻅的表达⽅式:
// 函数声明
function sum (num1, num2) {
return num1 + num2;
}
let sum = function(num1, num2) {
return num1 + num2;
};
// 函数声明和函数表达式两种⽅式
let sum = (num1, num2) => {
return num1 + num2;
};
3.4 其他引⽤类型
除了上述说的三种之外,还包括 Date 、 RegExp 、 Map 、 Set 等......
4 存储区别
基本数据类型和引⽤数据类型存储在内存中的位置不同:
当我们把变量赋值给⼀个变量时,解析器⾸先要确认的就是这个值是基本类型值还是引⽤类型值
下⾯来举个例⼦
4.1 基本类型
let a = 10;
let b = a; // 赋值操作
b = 20;
console.log(a); // 10值
a 的值为⼀个基本类型,是存储在栈中,将 a 的值赋给 b ,虽然两个变量的值相等,但是两个变量保存了两个不同的内存地址
下图演⽰了基本类型赋值的过程:

4.2 引⽤类型
var obj1 = {}
var obj2 = obj1;
obj2.name = "Xxx";
console.log(obj1.name); // xxx
引⽤类型数据存放在堆中,每个堆内存对象都有对应的引⽤地址指向它,引⽤地址存放在栈中。
obj1 是⼀个引⽤类型,在赋值操作过程汇总,实际是将堆内存对象在栈内存的引⽤地址复制了⼀份给了 obj2 ,实际上他们共同指向了同⼀个堆内存对象,所以更改 obj2 会对 obj1 产⽣影响
下图演⽰这个引⽤类型赋值过程

5 ⼩结
- 声明变量时不同的内存地址分配:
- 简单类型的值存放在栈中,在栈中存放的是对应的值
- 引⽤类型对应的值存储在堆中,在栈中存放的是指向堆内存的地址
- 不同的类型数据导致赋值变量时的不同:
- 简单类型赋值,是⽣成相同的值,两个对象对应不同的地址
- 复杂类型赋值,是将保存对象的内存地址赋值给另⼀个变量。也就是两个变量指向堆内存中同⼀个对象