JavaScript 是一种动态类型语言,这意味着变量在声明时不需要指定类型。根据数据存储方式的不同,JavaScript 中的数据类型可以分为两大类:简单(原始)数据类型和复杂(引用)数据类型。下面详细介绍每种数据类型及其注意事项。
1. 简单数据类型
简单数据类型是按值存储的,这意味着当我们将一个简单类型的数据复制给另一个变量时,实际上是复制了该值的一个副本。如果改变其中一个变量的值,不会影响到另一个变量。JavaScript 中的简单数据类型包括:
1.1 number
-
用于表示数字,无论是整数还是浮点数。
-
注意:由于 JavaScript 使用 IEEE 754 标准来表示数字,存在精度问题。例如,
0.1 + 0.2 !== 0.3
。 -
特殊值:
Infinity
、-Infinity
和NaN
(Not-a-Number)。 -
示例:
let a = 0.1;
let b = 0.2;
console.log(a+b);//输出:0.30000000000000004
1.2 bigint
-
用于表示任意大小的整数。
-
创建方式:使用后缀
n
,例如1n
。 -
注意:
bigint
不能与number
类型进行混合运算,需要显式转换。 -
不能使用
==
、!=
、===
、!==
等运算符与number
比较。 -
示例:
// 数字范围有限
//let num1 = 999999999999999999999;
//let num2 = 14561561654815623186;
//console.log(num1 + num2);输出:1.0145615616548156e+21
let num1 = 999999999999999999999n;
let num2 = 14561561654815623186n;
console.log(num1 + num2);//输出:1014561561654815623185n
1.3 string
-
用于表示文本数据。
-
字符串可以使用单引号
'
或双引号"
包围。 -
模板字符串:使用反引号
`
包围,支持多行和表达式插值。 -
示例:
let name = 'Alice';
let greeting = `Hello, ${name}!`;
console.log(greeting); // Hello, Alice!
1.4 boolean
-
用于表示逻辑值,即
true
或false
。 -
布尔值常用于条件判断。
-
示例:
let isTrue = true;
if (isTrue) {
console.log('It is true.');
}
1.5 undefined
-
表示一个变量已被声明,但尚未被赋值的状态。
-
注意:未初始化的变量默认值为
undefined
。 -
示例:
let x;
console.log(x); // undefined
1.6 null
-
表示一个空值或不存在的对象,是一个特殊的值,可以被赋值给变量。也可以赋值给一个对象,这个对象将被垃圾回收器回收
-
注意:
typeof null
返回"object"
,这是一个历史遗留问题。 -
示例:
let y = null;
console.log(y); // null
console.log(typeof y); // "object"
1.7 symbol
-
表示独一无二的值,常用于对象属性的标识,确保属性名不会冲突。
-
创建方式:使用
Symbol()
函数。 -
即使使用相同的描述字符串调用
Symbol()
,每次也会得到一个不同的Symbol
实例。 -
示例:
let id1 = Symbol('id');
let id2 = Symbol('id');
console.log(id1 === id2); // false
2. 复杂数据类型
引用数据类型是按引用存储的,这意味着当我们把一个引用类型的数据赋值给另一个变量时,实际上复制的是该数据在内存中的地址。因此,对其中一个变量的修改会影响到另一个变量。JavaScript 中的主要复杂数据类型是:
2.1 object
-
用于存储复杂的数据结构,如数组、函数、日期等。
-
对象在内存中是以堆(heap)的方式存储的。
-
示例:
let obj1 = { name: 'Alice' };
let obj2 = obj1;
obj2.name = 'Bob';
console.log(obj1.name); // Bob
3. 内存分配机制
3.1 栈(Stack):用于存储原始数据类型。
-
访问速度快,但空间有限。
-
当一个原始类型的数据被创建时,它的值会直接存储在栈中。
-
当一个原始类型的数据被赋值给另一个变量时,实际上是复制了该值的一个副本。因此,修改其中一个变量的值不会影响到另一个变量。
-
示例:
let a = 10;
let b = a;
b = 20;
console.log(a); // 10
console.log(b); // 20
3.2 堆(Heap):用于存储引用数据类型。
-
空间比栈大得多,但访问速度相对较慢。
-
当一个引用类型的数据被创建时,实际的数据会被存储在堆中,而栈中只保存指向这些数据的指针。
-
当一个引用类型的数据被赋值给另一个变量时,实际上是复制了该数据在内存中的地址。因此,修改其中一个变量的值会影响到另一个变量。
-
示例:
let obj1 = { name: 'Alice' };
let obj2 = obj1;
obj2.name = 'Bob';
console.log(obj1.name); // Bob
3.3 图解
4. 总结
JS数据类型可以是两种,可以是七种,也可以是八种。原始数据类型按值存储在栈中,引用数据类型按引用存储在堆中。把基础打牢,打结实,这样面对不同的面试官不是易如反掌?