js的数据类型
JavaScript 目前包含八种数据类型,其中可以分成两大类。
基本数据类型(原始值):
- Number(数值,包含NaN)
- String(字符串)
- Boolean(布尔值)
- Undefined(未定义/未初始化)
- Null(空对象)
- Symbol(独一无二的值,ES6 新增)
- BigInt (大整数,能够表示超过 Number 类型大小限制的整数,ES 2020新增)
引用数据类型(引用值):
- Object(对象。Array/数组 和 function/函数 也属于对象的一种)
基本数据类型的值是不可变的,你无法修改值本身,你只能给代表它的变量重新赋值,将原来的值覆盖。而引用数据类型是可变的------它们的值是可修改的。
7种基本数据类型除了 Null
和 Undefined
之外,其他基本数据类型(String
、Number
、Boolean
、Symbol
、BigInt
)都可以通过对象包装器(也称为包装对象)来创建对应的对象。这些包装对象提供了额外的方法和属性,使得基本数据类型可以像对象一样使用。
基本数据类型
Null和Undefined
Null
和 Undefined
没有对应的包装对象。Null
类型对应唯一值null
,Undefined
类型对应唯一值undefined
Number
-
定义:用于表示整数和浮点数。
-
特点:
- JavaScript 中的数字是双精度浮点数(64位)。
- 包括整数、小数、正数、负数、科学计数法等。
-
构造函数和普通函数
-
当
Number
作为普通函数调用时,它将参数强制转换为数字原始值。BigInt 被转换为数字。如果值不能转换,则返回NaN
。
javascript
const a = new Number("123"); // a === 123 为 false
const b = Number("123"); // b === 123 为 true
a instanceof Number; // 为 true
b instanceof Number; // 为 false
typeof a; // "object"
typeof b; // "number"
Number("unicorn"); // NaN
Number(undefined); // NaN
String
-
定义:由字符组成的序列,用于表示文本数据。
-
特点:
- 字符串是不可变的,每次对字符串的操作都会返回一个新的字符串。
- 可以使用单引号(
'
)、双引号("
)或反引号(`````)定义字符串。
-
构造函数和普通函数
-
当
String
作为构造函数(使用new
)被调用时,它会创建一个String
对象,该对象不是原始类型。 -
当
String
作为函数被调用时,它会将参数强制转换为一个字符串原始类型。Symbol 值会被转换成"Symbol(description)"
,其中description
是该 Symbol 的 description 属性值,而不会抛出错误。
-
日常使用中很少需要使用String作为构造函数,常用的就是String()
强制类型转换和String的实例方法
Boolean
-
定义 :布尔值只有两个值:
true
和false
。 -
特点:
- 常用于逻辑判断。
- 在 JavaScript 中,有些值在布尔上下文中会被视为"真值"(truthy),有些会被视为"假值"(falsy)。
-
构造函数和普通函数
作为第一个参数传递的值被转换为布尔值 。如果该值被省略或为 0
、-0
、0n
、null
、false
、NaN
、undefined
或空字符串(""
),那么该对象的初始值为 false
。所有其他的值,包括任何对象、空数组([]
)或字符串 "false"
,都会创建一个初始值为 true
的对象。
javascript
const bZero = new Boolean(0);
const bNull = new Boolean(null);
const bEmptyString = new Boolean("");
const bfalse = new Boolean(false);
typeof bfalse; // "object"
Boolean(bfalse); // true
请注意,用 Boolean()
将 Boolean
对象转换为原始值的结果总是 true
,即使该对象的值为 false
。因此,总是建议避免构造 Boolean
包装对象。
Symbol
-
定义:是一种唯一的、不可变的数据类型,主要用于创建对象的唯一属性名。
-
特点:
- 每次调用
Symbol()
都会返回一个唯一的符号值。 - 符号值是唯一的,即使两个符号的描述相同,它们也是不同的。
- 每次调用
ini
let sym1 = Symbol('mySymbol');
let sym2 = Symbol('mySymbol');
console.log(sym1 === sym2); // 输出 false
symbol 是一种原始数据类型。Symbol()
函数会返回 symbol 类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的 symbol 注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()
"。
每个从 Symbol()
返回的 symbol 值都是唯一的。一个 symbol 值能作为对象属性的标识符;这是该数据类型仅有的目的。更进一步的解析见------glossary entry for Symbol。
javascript
const symbol1 = Symbol();
const symbol2 = Symbol(42);
const symbol3 = Symbol("foo");
console.log(typeof symbol1);
// Expected output: "symbol"
console.log(symbol2 === 42);
// Expected output: false
console.log(symbol3.toString());
// Expected output: "Symbol(foo)"
console.log(Symbol("foo") === Symbol("foo"));
// Expected output: false
BigInt
-
定义 :用于表示大于
2^53 - 1
的整数。 -
特点:
- 从 ECMAScript 2020 开始引入。
- 使用
n
后缀表示大整数。
BigInt
可以表示任意大的整数。
可以用在一个整数字面量后面加 n
的方式定义一个 BigInt
,如:10n
,或者调用函数 BigInt()
(但不包含 new
运算符)并传递一个整数值或字符串值。
javascript
const theBiggestInt = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
// ↪ 9007199254740991n
const hugeString = BigInt("9007199254740991");
// ↪ 9007199254740991n
const hugeHex = BigInt("0x1fffffffffffff");
// ↪ 9007199254740991n
const hugeBin = BigInt(
"0b11111111111111111111111111111111111111111111111111111",
);
// ↪ 9007199254740991n
它在某些方面类似于 Number
,但是也有几个关键的不同点:不能用于 Math
对象中的方法;不能和任何 Number
实例混合运算,两者必须转换成同一种类型。在两种类型来回转换时要小心,因为 BigInt
变量在转换成 Number
变量时可能会丢失精度。
引用数据类型
在 JavaScript 中,引用数据类型(也称为复杂数据类型或对象类型)是指存储在内存中的对象,通过引用(内存地址)来访问。与基本数据类型不同,引用数据类型是可变的,可以包含多个值或属性。
以下是 JavaScript 中常见的引用数据类型及其特点:
1. Object(对象)
-
定义:对象是 JavaScript 中的基本数据结构,用于存储键值对(属性和方法)。
-
特点 :
- 对象是可变的,可以动态添加、删除或修改属性。
- 对象的属性可以是基本数据类型或引用数据类型。
-
创建方式 :
- 使用对象字面量
{}
。 - 使用
new Object()
。
- 使用对象字面量
-
示例 :
javascriptlet person = { firstName: "John", lastName: "Doe", age: 30, greet: function () { console.log("Hello, " + this.firstName + " " + this.lastName); } }; console.log(person.firstName); // 输出 "John" person.greet(); // 输出 "Hello, John Doe"
2. Array(数组)
-
定义:数组是一种特殊的对象,用于存储有序的值集合。
-
特点 :
- 数组的元素可以是任意类型,包括基本数据类型或引用数据类型。
- 数组的长度是动态的,可以随时添加或删除元素。
-
创建方式 :
- 使用数组字面量
[]
。 - 使用
new Array()
。
- 使用数组字面量
-
示例 :
javascriptlet fruits = ["Apple", "Banana", "Cherry"]; console.log(fruits[1]); // 输出 "Banana" fruits.push("Date"); // 添加新元素 console.log(fruits.length); // 输出 4
3. Function(函数)
-
定义:函数是一段可以重复使用的代码块,用于执行特定任务。
-
特点 :
- 函数是 JavaScript 中的一等公民,可以作为值传递、赋值或存储在变量中。
- 函数可以有参数和返回值。
-
创建方式 :
- 使用函数声明。
- 使用函数表达式。
- 使用
new Function()
。
-
示例 :
javascriptfunction add(a, b) { return a + b; } let result = add(3, 4); console.log(result); // 输出 7 let multiply = function (a, b) { return a * b; }; console.log(multiply(3, 4)); // 输出 12
4. Date(日期)
-
定义:用于表示日期和时间的对象。
-
特点 :
- 提供了多种方法来操作日期和时间。
- 可以获取当前日期和时间,也可以设置特定的日期和时间。
-
创建方式 :
- 使用
new Date()
。
- 使用
-
示例 :
javascriptlet now = new Date(); console.log(now); // 输出当前日期和时间 let birthday = new Date("1990-01-01"); console.log(birthday.getFullYear()); // 输出 1990 console.log(birthday.getMonth() + 1); // 输出 1(月份从 0 开始) console.log(birthday.getDate()); // 输出 1
5. RegExp(正则表达式)
-
定义:用于描述字符串的模式,用于匹配、搜索和替换字符串。
-
特点 :
- 提供了强大的字符串操作功能。
- 可以使用正则表达式字面量或
new RegExp()
创建。
-
创建方式 :
- 使用正则表达式字面量
/pattern/
。 - 使用
new RegExp("pattern")
。
- 使用正则表达式字面量
-
示例 :
javascriptlet regex = /hello/i; // 不区分大小写 let str = "Hello World"; console.log(regex.test(str)); // 输出 true console.log(str.match(regex)); // 输出 ["Hello"]
6. Map(映射)
-
定义:一种键值对集合,键可以是任意类型。
-
特点 :
- 键值对的顺序是按照插入顺序保存的。
- 可以使用任意类型的值作为键。
-
创建方式 :
- 使用
new Map()
。
- 使用
-
示例 :
javascriptlet map = new Map(); map.set("key1", "value1"); map.set(2, "value2"); console.log(map.get("key1")); // 输出 "value1" console.log(map.size); // 输出 2
7. Set(集合)
-
定义:一种存储唯一值的集合。
-
特点 :
- 集合中的值是唯一的,不允许重复。
- 可以使用任意类型的值。
-
创建方式 :
- 使用
new Set()
。
- 使用
-
示例 :
javascriptlet set = new Set(); set.add("apple"); set.add("banana"); set.add("apple"); // 重复值不会被添加 console.log(set.size); // 输出 2 console.log(set.has("banana")); // 输出 true
8. Promise(承诺)
-
定义:用于异步操作的对象,表示一个可能尚未完成的操作。
-
特点 :
- 可以处理异步任务,例如网络请求或定时器。
- 状态可以是
pending
(进行中)、fulfilled
(已完成)或rejected
(已拒绝)。
-
创建方式 :
- 使用
new Promise()
。
- 使用
-
示例 :
javascriptlet promise = new Promise((resolve, reject) => { setTimeout(() => { resolve("Promise resolved!"); }, 1000); }); promise.then((result) => { console.log(result); // 输出 "Promise resolved!" });
9. Error(错误)
-
定义:用于表示错误的对象。
-
特点 :
- 可以抛出错误并捕获错误。
- 提供了错误信息和堆栈跟踪。
-
创建方式 :
- 使用
new Error()
。
- 使用
-
示例 :
javascripttry { throw new Error("Something went wrong"); } catch (e) { console.log(e.message); // 输出 "Something went wrong" }
10. 其他内置对象
JavaScript 还提供了一些其他内置对象,例如:
Math
:提供数学常量和函数。JSON
:用于解析和序列化 JSON 数据。Global
:全局对象,提供全局属性和方法。
引用数据类型的特点
- 可变性:引用数据类型是可变的,可以通过修改对象的属性或数组的元素来改变其内容。
- 引用传递:当将一个引用数据类型的值赋给另一个变量时,实际上是将引用(内存地址)赋值,而不是复制整个对象或数组。
- 内存管理:引用数据类型存储在堆内存中,垃圾回收机制会自动清理不再使用的对象。
示例:引用传递
javascript
let obj1 = { name: "John" };
let obj2 = obj1;
obj2.name = "Jane";
console.log(obj1.name); // 输出 "Jane"(因为 obj1 和 obj2 指向同一个对象)