前言
本篇对JavaScript常见数据类型和数据结构进行学习总结
三、常见数据类型和数据结构
String 对象
String 对象用于处理文本(字符串)。
const txt = new String("string");
或者更简单方式:
const txt = "string";
属性和方法
- 字符串长度:要获取一个字符串的长度,使用
length
属性。
const str = "Hello,World!";
console.log(str.length); // 输出:7
- 字符串拼接:使用
+
运算符或concat()
方法来连接两个或多个字符串。
const str1 = "Hello";
const str2 = "World";
const result1 = str1 + str2; // 使用 +
const result2 = str1.concat(str2); // 使用 concat() 方法
console.log(result1); // 输出:"HelloWorld"
console.log(result2); // 输出:"HelloWorld"
- 访问字符:使用方括号和从0开始的索引来访问字符串中的单个字符。
const str = "JavaScript";
console.log(str[0]); // 输出:"J"
console.log(str.charAt(4)); // 输出:"S"
- 子字符串:要从字符串中提取子字符串,使用
substring()
方法或slice()
方法。
const str = "JavaScript";
console.log(str.substring(0, 4)); // 输出:"Java"
console.log(str.slice(4, 10)); // 输出:"Script"
- 搜索子字符串:使用
indexOf()
方法或lastIndexOf()
方法在字符串中搜索子字符串,未找到匹配则返回-1(区分大小写)。
const str = "Hello,World!";
console.log(str.indexOf("World")); // 输出:3("World"的第一次出现位置)
console.log(str.lastIndexOf("World")); // 输出:3("World"的最后一次出现位置)
- 大小写转换:使用
toUpperCase()
方法将字符串转换为大写,使用toLowerCase()
方法将字符串转换为小写。
const str = "Hello, World!";
console.log(str.toUpperCase()); // 输出:"HELLO, WORLD!"
console.log(str.toLowerCase()); // 输出:"hello, world!"
- 拆分和连接:使用
split()
方法将字符串根据指定的分隔符拆分成字符串数组,不改变原始字符串,使用join()
方法将字符串数组连接成单个字符串。
const str = "苹果,香蕉,橘子";
const fruitsArray = str.split(",");
console.log(fruitsArray); // 输出:["苹果", "香蕉", "橘子"]
const fruitsString = fruitsArray.join(" 和 ");
console.log(fruitsString); // 输出:"苹果 和 香蕉 和 橘子"
- 去除空格:使用
trim()
方法去除字符串两端的空格。
const str = " Hello, World! ";
console.log(str.trim()); // 输出:"Hello, World!"
- 字符串替换:使用
replace()
方法将字符串中匹配到的首个子串替换为新的内容。
const str = "Hello, World!";
const newStr = str.replace("World", "JavaScript");
console.log(newStr); // 输出:"Hello, JavaScript!"
- 字符串比较:使用
localeCompare()
方法来比较两个字符串,并返回一个表示比较结果的数字。
const str1 = "apple";
const str2 = "banana";
const result = str1.localeCompare(str2);
console.log(result); // 输出:-1(表示str1在字典顺序上排在str2之前)
- 字符串包含判断:使用
includes()
方法来判断一个字符串是否包含另一个子字符串(区分大小写),返回一个布尔值。
const str = "Hello, World!";
console.log(str.includes("Hello")); // 输出:true
console.log(str.includes("JavaScript")); // 输出:false
- 字符串反转:使用
split()
和reverse()
方法将字符串反转。
const str = "Hello";
const reversedStr = str.split("").reverse().join("");
console.log(reversedStr); // 输出:"olleH"
- 字符串是否为特定开头:使用
startsWith
进行判断。
const message = 'Error: foo is not defined'
message.starsWith('Error') // true
- 字符串是否为特定结尾:使用
endsWith
进行判断。
const message = 'Error: foo is not defined'
message.endsWith('.') // true
注意:字符串是不可变的,这意味着这些方法并不会修改原始字符串,而是返回一个新的带有所需更改的字符串。
模板字符串
模板字符串是 ES6(ECMAScript 2015)引入的新特性,模板字符串是一种特殊类型的字符串,它允许在字符串中插入表达式或变量,并支持多行文本的表示。模板字符串使用反引号(` `)来包围文本,并使用${expression}
语法来插入表达式。
下面是模板字符串的一些基本用法:
- 插入表达式:
const name = "Flynn";
const age = 21;
const message = `My name is ${name} and I am ${age} years old.`;
console.log(message); // 输出:"My name is Flynn and I am 21 years old."
- 多行文本,无需
/n
直接使用回车:
const multiLineText = `
This is a
multi-line
text using
template strings.`;
console.log(multiLineText);
// 输出:
// "This is a
// multi-line
// text using
// template strings."
- 嵌套使用:
const item = {
name: "Book",
price: 20,
};
const itemInfo = `
Item:
Name: ${item.name}
Price: $${item.price}
`;
console.log(itemInfo);
// 输出:
// "Item:
// Name: Book
// Price: $20"
在模板字符串中,${expression}
中的expression
可以是任意的 JavaScript 表达式,它会在模板字符串中被求值,并将其结果插入到字符串中。使用模板字符串可以让字符串拼接更加简洁和易读,并且避免了手动的字符串连接操作。它在处理多行文本和动态内容时特别有用。
Array 对象
Array对象是一个内置对象,用于表示有序的、可变的集合。数组可以包含任意类型的数据,包括基本数据类型和对象,它提供了各种属性和方法来操作和处理数组。
- 创建数组:使用数组字面量表示法创建一个数组,也可以使用Array构造函数来创建数组。
// 使用数组字面量
const numbers = [1, 2, 3, 4, 5];
// 使用Array构造函数
const fruits = new Array("apple", "banana", "orange");
- 访问数组元素:使用索引来访问数组中的元素,索引从0开始。
const fruits = ["apple", "banana", "orange"];
console.log(fruits[0]); // 输出:"apple"
console.log(fruits[2]); // 输出:"orange"
- 修改数组元素:通过索引来修改数组中的元素。
const numbers = [1, 2, 3, 4, 5];
numbers[2] = 10;
console.log(numbers); // 输出:[1, 2, 10, 4, 5]
- 数组长度:使用
length
属性获取数组的长度。
const fruits = ["apple", "banana", "orange"];
console.log(fruits.length); // 输出:3
- 添加元素:使用
push()
方法在数组末尾添加一个或多个元素。
const fruits = ["apple", "banana"];
fruits.push("orange");
console.log(fruits); // 输出:["apple", "banana", "orange"]
- 删除元素:使用
pop()
方法从数组末尾删除一个元素,使用shift()
方法从数组头部删除一个元素。
const fruits = ["apple", "banana", "orange"];
fruits.pop(); // 删除末尾的元素
console.log(fruits); // 输出:["apple", "banana"]
fruits.shift(); // 删除头部的元素
console.log(fruits); // 输出:["banana"]
- 数组合并:使用
concat()
方法将多个数组合并为一个新数组。
const fruits = ["apple", "banana"];
const moreFruits = ["orange", "grape"];
const allFruits = fruits.concat(moreFruits);
console.log(allFruits); // 输出:["apple", "banana", "orange", "grape"]
- 数组切片:使用
slice()
方法从数组中截取一部分形成新的数组。
const numbers = [1, 2, 3, 4, 5];
const slicedNumbers = numbers.slice(1, 4);
console.log(slicedNumbers); // 输出:[2, 3, 4]
- 数组排序:使用
sort()
方法对数组元素进行排序。
const fruits = ["banana", "apple", "orange"];
fruits.sort();
console.log(fruits); // 输出:["apple", "banana", "orange"]
- 数组搜索:使用
indexOf()
方法或includes()
方法来搜索数组中的元素。
const fruits = ["apple", "banana", "orange"];
console.log(fruits.indexOf("banana")); // 输出:1
console.log(fruits.includes("orange")); // 输出:true
at(index)
方法:在 ES2019 (ECMAScript 10) 中被引入。用于获取数组中指定索引位置的元素值。如果索引超出数组的范围,将返回undefined
。
const fruits = ["apple", "banana", "orange"];
console.log(fruits.at(1)); // 输出:"banana"
console.log(fruits.at(5)); // 输出:undefined
shift()
方法:用于删除数组的第一个元素,并返回被删除的元素。该操作会改变原数组的内容,使后续元素的索引减 1。
const fruits = ["apple", "banana", "orange"];
const shiftedElement = fruits.shift();
console.log(fruits); // 输出:["banana", "orange"]
console.log(shiftedElement); // 输出:"apple"
Object 对象
Object 对象是一种基本的数据类型,也是一种复杂的数据结构,用于表示一组键值对(属性和值)的无序集合。对象可以包含其他对象、数组、函数等数据类型。对象的键是字符串或符号类型(ES6引入),值可以是任意数据类型,包括基本数据类型和对象。
创建对象
对象的创建可以通过对象字面量、构造函数或Object.create()方法来实现。
- 使用对象字面量创建对象:
const person = {
name: "Flynn",
age: 21,
job: "Programmer"
};
- 使用构造函数创建对象:
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
}
const person = new Person("Flynn", 21, "Programmer");
- 使用Object.create()方法创建对象:
const personPrototype = {
greet: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
const person = Object.create(personPrototype);
person.name = "Flynn";
person.age = 21;
person.job = "Programmer";
对象的属性可以通过点号(.)或方括号([])访问。
const person = {
name: "Flynn",
age: 21,
job: "Programmer"
};
console.log(person.name); // 输出:"Flynn"
console.log(person["age"]); // 输出:21
对象还可以包含函数作为属性,这些函数被称为对象的方法。
const person = {
name: "Flynn",
age: 21,
sayHello: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
person.sayHello(); // 输出:"Hello, my name is Flynn"
在对象中添加、修改和删除属性的值也是非常常见的操作。
const person = {
name: "Flynn",
age: 21,
};
person.job = "Programmer"; // 添加属性
person.age = 22; // 修改属性值
delete person.name; // 删除属性
console.log(person); // 输出:{ age: 22, job: "Programmer" }
方法
使用Object.assign()
,合并对象
// 声明两个变量
const food = { color: 'blue'};
const clothes = { brand: 'Guess'};
const result = Object.assign({ companyName: "XYZ" }, food, clothes);
console.log(result); //输出: { companyName: "XYZ", color: "blue", brand: "Guess" }
// 声明两个变量
const customer = { fName: 'Jin', lName: 'Necesario', handsome: true };
// 使用Object.assign(),克隆对象。
const clonedCustomer = Object.assign({}, customer);
//The output would be: {fName: "Jin", lName: "Necesario", handsome: true}
console.log(clonedCustomer);
Object.keys()
:将对象中的key值存储在数组中
let obj={
a:"值1",
b:"值2",
c:"值3",
}
console.log(Object.keys(obj)); // 输出["a", "b", "c"]
Object.values()
:将对象的value值存储在数组中
let obj={
a:"值1",
b:"值2",
c:"值3",
}
console.log(Object.keys(obj)); // 输出["a", "b", "c"]
Object.entries()
返回一个数组,其元素是与直接在 Object 上找到的可枚举属性键值对相对应的数组。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}
Map 对象
Map 是一种数据结构,用于存储键值对的有序集合。与普通的对象相比,Map 提供了更灵活和强大的功能,它可以使用任意类型的值作为键(包括对象、函数等),而不仅仅限于字符串或符号。另外,Map 中的键值对是有序的,插入顺序会被保留。
创建 Map 对象可以使用构造函数 Map()
。
const myMap = new Map();
添加键值对可以使用 set()
方法。
const myMap = new Map();
myMap.set("name", "Flynn");
myMap.set("age", 21);
获取键值对的值可以使用 get()
方法。
const myMap = new Map();
myMap.set("name", "Flynn");
myMap.set("age", 21);
console.log(myMap.get("name")); // 输出:"Flynn"
console.log(myMap.get("age")); // 输出:21
检查 Map 中是否存在某个键可以使用 has()
方法。
const myMap = new Map();
myMap.set("name", "Flynn");
myMap.set("age", 21);
console.log(myMap.has("name")); // 输出:true
console.log(myMap.has("job")); // 输出:false
删除键值对可以使用 delete()
方法。
const myMap = new Map();
myMap.set("name", "Flynn");
myMap.set("age", 21);
myMap.delete("name");
console.log(myMap.has("name")); // 输出:false
获取 Map 中的键或值可以使用 keys()
、values()
和 entries()
方法。
const myMap = new Map();
myMap.set("name", "Flynn");
myMap.set("age", 21);
const keys = myMap.keys();
const values = myMap.values();
const entries = myMap.entries();
console.log([...keys]); // 输出:["name", "age"]
console.log([...values]); // 输出:["Flynn", 21]
console.log([...entries]); // 输出:[["name", "Flynn"], ["age", 21]]
Map 还有其他一些常用的方法,如 size
属性用于获取 Map 中键值对的数量,clear()
方法用于清空 Map 中的所有键值对等。
const myMap = new Map();
myMap.set("name", "Flynn");
myMap.set("age", 21);
console.log(myMap.size); // 输出:2
myMap.clear();
console.log(myMap.size); // 输出:0
将Object转换为Map
new Map()
构造函数接受一个可迭代的entries
。借助Object.entries()
方法可以很容易的将Object转换为Map:
const obj = { foo: "bar", baz: 42 };
const map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }
Object与Map差异
Object | Map | |
---|---|---|
键的类型 | 只能是字符串或符号(ES6之前不支持符号) | 可以是任意数据类型,包括对象、函数等 |
键的顺序 | 无序(在实现中可能有一定的顺序,但不保证保留插入顺序) | 有序,保留插入顺序 |
遍历方法 | 使用 for...in 或 Object.keys() | 使用 forEach() , for...of 或 Map 的迭代器方法 |
大小属性 | 无 | 使用 size 属性获取键值对的数量 |
性能 | 在大型数据集上性能相对较差,特别是在添加和删除键值对时 | 在大型数据集上性能相对较好,特别是在添加和删除键值对时 |
使用场景 | 通常用于普通的键值对映射和对象属性的管理 | 当需要保留插入顺序、键可以是任意类型时使用 |
其他 | 具有原型链,可能导致一些意外的键冲突 | 不具有原型链,不会有键冲突的问题 |
注意:对于简单的键值对映射和对象属性管理,Object 是一种常见的选择;而对于需要保留插入顺序,键可以是任意类型的情况,Map 提供了更灵活和强大的功能。
Set 对象
Set 是 ES6引入的一种数据结构,它是一组无序、唯一的元素的集合。Set 中的元素是不重复的,即使尝试添加相同的元素多次,它也只会保留一个副本。Set 中的元素可以是任意类型的数据,包括基本数据类型和对象。
Set 对象提供了些常用的方法来操作集合,例如添加元素、删除元素、检查元素是否存在等。
- 创建新的 Set 对象:其中的参数是一个可迭代对象(如数组或字符串),它的元素会被添加到 Set 中作为初始元素。
const mySet = new Set([1, 2, 3]);
- 添加元素:如果 Set 中已经存在该元素,则不会重复添加。
const mySet = new Set();
mySet.add(1);
mySet.add(2);
mySet.add(3);
mySet.add(1); // 这里的添加不会生效,因为元素 1 已经存在于 Set 中
- 删除元素:从 Set 中删除指定元素。
const mySet = new Set([1, 2, 3]);
mySet.delete(2); // 删除元素 2
- 检查 Set 中是否存在指定元素,返回一个布尔值。
const mySet = new Set([1, 2, 3]);
console.log(mySet.has(2)); // 输出:true
console.log(mySet.has(4)); // 输出:false
- 清空 Set 中的所有元素。
const mySet = new Set([1, 2, 3]);
mySet.clear(); // 清空 Set 中的元素
- 获取 Set 中元素的个数。
const mySet = new Set([1, 2, 3]);
console.log(mySet.size); // 输出:3
Set 对象的特点是可以确保其中的元素不重复,并且保留了元素插入的顺序。它在处理需要确保唯一性的数据集合时非常有用。请注意,Set 是一个迭代器对象,可以通过 for...of
循环或使用 forEach()
方法遍历其中的元素。
获取 Set中的键或值可以使用 keys()
、values()
和 entries()
方法,由于 Set 中的键和值是相同的,因此 keys()
方法的结果与 values()
方法相同。
const set = new Set([1, 2, 3]);
const keys = set.keys();
const values = set.values();
const entries = myMap.entries();
console.log([...keys]); // 输出:[1, 2, 3]
console.log([...values]); // 输出:[1, 2, 3]
console.log([...entries]); // 输出:[[1, 1], [2, 2], [3, 3]]
Set 是唯一值的集合;每个值在 Set 中只能出现一次;一个 Set 容纳任何数据类型的任何值。
对于 Set,typeof
返回object
:
typeof letters // 返回 object
Date 对象
Date 对象用于处理日期与时间。
创建 Date 对象:
创建一个 Date
对象可以使用 new Date()
构造函数,可以不带参数,此时会创建一个表示当前日期和时间的对象,也可以传递特定的日期和时间参数。
const d = new Date();
const d = new Date(milliseconds); // 参数为毫秒
const d = new Date(dateString);
const d = new Date(year, month, day, hours, minutes, seconds, milliseconds);
- milliseconds 参数是一个 Unix 时间戳(Unix Time Stamp),它是一个整数值,表示自 1970 年 1 月 1 日 00:00:00 UTC(the Unix epoch)以来的毫秒数。
- dateString 参数表示日期的字符串值。
- year, month, day, hours, minutes, seconds, milliseconds 分别表示年、月、日、时、分、秒、毫秒。
Date
对象提供了多种方法来获取日期和时间的各个部分,比如年、月、日、小时、分钟、秒等:
const future = new Date(2037, 10, 19, 15, 23);
console.log(future);
console.log(future.getFullYear()); // 从 Date 对象以四位数字返回年份。
console.log(future.getMonth()); // 从 Date 对象返回月份 (0 ~ 11)。
console.log(future.getDate()); // 从 Date 对象返回一个月中的某一天 (1 ~ 31)。
console.log(future.getDay()); // 从 Date 对象返回一周中的某一天 (0 ~ 6)。
console.log(future.getHours()); // 返回 Date 对象的小时 (0 ~ 23)。
console.log(future.getMinutes()); // 返回 Date 对象的分钟 (0 ~ 59)。
console.log(future.getSeconds()); // 返回 Date 对象的秒数 (0 ~ 59)。
console.log(future.toISOString()) // 使用 ISO 标准返回字符串的日期格式。
console.log(future.getTime()); // 返回 1970 年 1 月 1 日至今的毫秒数。
console.log(Date.now()); // 返回自1970年1月1日00:00:00 UTC以来经过的毫秒数。
future.setFullYear(2040); // 设置 Date 对象中的年份(四位数字)。
Date
对象还可以进行日期和时间的计算和比较,比如加减天数、比较两个日期的先后等:
const date1 = new Date(2023, 6, 31);
const date2 = new Date(2023, 7, 15);
// 计算两个日期之间的时间差(以毫秒为单位)
const timeDifference = date2 - date1;
// 加减天数
date1.setDate(date1.getDate() + 7);
// 比较两个日期的先后
if (date1 > date2) {
console.log("date1 在 date2 之后");
} else if (date1 < date2) {
console.log("date1 在 date2 之前");
} else {
console.log("两个日期相同");
}
注意:日期对象基于本地时间,它会考虑浏览器所在地区的时区和夏令时。在进行日期和时间的计算和比较时,应该注意时区的影响。