JavaScript API 可以分为几类,根据其提供的功能和用途:

  1. 浏览器 API: 这些 API 提供了与浏览器相关的功能和特性的接口,包括:
    • DOM API:文档对象模型(Document Object Model),用于操作和管理网页的内容和结构。
    • Fetch API:用于发起网络请求和处理响应的接口。
    • Canvas API:用于在网页上绘制图形的接口。
    • Web Storage API:提供了本地存储(localStorage 和 sessionStorage)的能力。
    • Web Workers API:允许在后台线程中执行脚本以避免阻塞主线程。
  • 浏览器 API: 大多数浏览器 API 是直接内置在现代浏览器中的,不需要额外的导入或下载。您可以通过 JavaScript 直接访问这些 API。例如,DOM API、Fetch API、Canvas API 等都是浏览器原生支持的,可以直接在网页中使用。

  1. 第三方 API: 这些 API 由第三方服务提供,通过网络请求或其他方式提供特定服务的接口,如 Google Maps API、Twitter API 等。
  2. Node.js API: 如果在 Node.js 环境中使用 JavaScript,可以访问 Node.js 提供的一组 API,如文件系统 API、HTTP 模块等。
  3. WebRTC API: 用于实时通信(如视频聊天)的 WebRTC API。
  4. 多媒体 API: 包括音频和视频处理的 API,如 Web Audio API 和 MediaStream API。

使用和优势

JavaScript API 的主要优势包括:

  • 跨平台性: 可以在多种设备和操作系统上运行,只要支持相应浏览器或环境。
  • 标准化: 遵循标准规范,保证了兼容性和可靠性。
  • 功能丰富: 提供了丰富的功能和接口,使开发者能够实现各种复杂的功能和交互。
  • 社区支持: 受到广泛的开发者社区支持和文档资料,便于学习和使用。

总之,JavaScript API 是 JavaScript 开发中不可或缺的一部分,它使得开发者能够利用浏览器和其他环境的强大功能来构建各种交互式和动态的应用程序。

Object.assign

Object.assign 是 JavaScript 中一个用于复制对象属性的方法。它可以将一个或多个源对象的可枚举属性复制到目标对象,并返回目标对象。以下是对 Object.assign 方法的详细解释及其用法示例:

基本语法

1
Object.assign(target, ...sources)
  • target: 目标对象。属性会被复制到这个对象上。
  • …sources: 一个或多个源对象。属性将从这些对象中复制。
  1. 合并多个源对象
1
2
3
4
5
6
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);

console.log(target); // { a: 1, b: 2, c: 3 }
  1. 属性覆盖
1
2
3
4
5
const target = { a: 1, b: 1 };
const source = { b: 2, c: 3 };
Object.assign(target, source);

console.log(target); // { a: 1, b: 2, c: 3 }
  1. 浅拷贝

Object.assign 进行的是浅拷贝,如果源对象的属性值是对象,则只会复制对象的引用。

1
2
3
4
5
6
7
8
9
const target = { a: 1 };
const source = { b: { c: 2 } };
Object.assign(target, source);

console.log(target); // { a: 1, b: { c: 2 } }

// 修改 source.b.c
source.b.c = 3;
console.log(target); // { a: 1, b: { c: 3 } }
  1. 处理原始值

非对象类型的源会被忽略,但若目标是非对象类型则会抛出错误。

1
2
3
4
5
const target = { a: 1 };
const source = 'string';
Object.assign(target, source);

console.log(target); // { a: 1 }

注意事项

  • Object.assign 方法不会跳过那些值为 null 或 undefined 的源对象。
  • 不会深拷贝对象中的嵌套对象,只会复制对象的引用。
  • 属性名相同的情况下,后面的属性会覆盖前面的属性。

应用场景

  • 合并多个对象。
  • 浅拷贝一个对象。
  • 给对象添加新的属性或方法。

对象比较方法

总结一下在JavaScript中比较两个对象的属性值的方法:

1. 使用 JSON.stringify

这种方法适用于对象属性顺序相同且没有循环引用的简单对象。

1
2
3
4
5
6
7
8
9
10
11
function areObjectsEqual(obj1, obj2) {
return JSON.stringify(obj1) === JSON.stringify(obj2);
}

// 示例
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };
const obj3 = { a: 1, b: 3 };

console.log(areObjectsEqual(obj1, obj2)); // true
console.log(areObjectsEqual(obj1, obj3)); // false

2. 递归比较对象属性

这种方法适用于比较复杂和嵌套的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function areObjectsEqual(obj1, obj2) {
// 检查是否是同一个引用
if (obj1 === obj2) return true;

// 检查是否是对象类型
if (obj1 == null || obj2 == null || typeof obj1 !== 'object' || typeof obj2 !== 'object') {
return false;
}

// 获取对象的键列表
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);

// 检查键的数量是否相同
if (keys1.length !== keys2.length) return false;

// 递归比较每个键的值
for (let key of keys1) {
if (!keys2.includes(key) || !areObjectsEqual(obj1[key], obj2[key])) {
return false;
}
}

return true;
}

// 示例
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
const obj3 = { a: 1, b: { c: 3 } };

console.log(areObjectsEqual(obj1, obj2)); // true
console.log(areObjectsEqual(obj1, obj3)); // false

3. 使用 lodash 库

lodash 提供了一个强大的 isEqual 方法来进行深度比较。

首先,安装 lodash:

1
npm install lodash

然后使用它来比较对象:

1
2
3
4
5
6
7
8
const _ = require('lodash');

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
const obj3 = { a: 1, b: { c: 3 } };

console.log(_.isEqual(obj1, obj2)); // true
console.log(_.isEqual(obj1, obj3)); // false

4. 不可行的方法:使用 {…obj1} === {…obj2}

使用扩展运算符 {…obj} 进行对象比较不可行,因为这会创建新的对象引用,即使内容相同,引用不同的对象比较时会返回 false。

1
2
3
4
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };

console.log({...obj1} === {...obj2}); // false

总结

  • JSON.stringify: 简单、快速,但仅适用于属性顺序相同且没有循环引用的对象。
  • 递归比较: 更复杂但更通用,适用于嵌套对象。
  • lodash 的 isEqual: 简单、强大,但需要引入第三方库。
  • {…obj1} === {…obj2}: 不可行,因为它比较的是对象的引用而不是内容。

根据具体的需求选择适合的方法来比较对象的属性值。

new AbortController()

AbortController 是一个用于控制 Fetch API 请求的标准 JavaScript API。它允许您在请求尚未完成时终止(取消)请求。这在需要管理多个并行请求或需要用户取消请求的情况下特别有用。

具体来说,AbortController 允许您执行以下操作:

  1. 创建控制器: 使用 new AbortController() 创建一个新的 AbortController 实例。
  2. 终止请求: 调用控制器的 abort() 方法可以立即终止与该控制器关联的任何 Fetch 请求。

例如,以下是使用 AbortController 和 Fetch API 来发起请求并处理取消请求的简单示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const controller = new AbortController();
const signal = controller.signal;

// 创建 Fetch 请求
fetch('https://api.example.com/data', { signal })
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('Fetch aborted');
} else {
console.error('Fetch error:', error);
}
});

// 取消请求示例
setTimeout(() => controller.abort(), 5000); // 在5秒后取消请求

在这个示例中:

  • new AbortController() 创建了一个新的 AbortController 实例 controller
  • controller.signal 提供了一个 AbortSignal 对象,该对象可以传递给 Fetch 请求的 signal 选项,以便在请求被取消时通知 Fetch 请求。
  • controller.abort() 方法在需要时可以调用,以取消与该控制器关联的 Fetch 请求。

什么是Map?
‘Map’ 是 JavaScript 中的一种数据结构,用于存储键值对(key-value pairs)。它提供了更灵活的键类型和有序的插入顺序,相对于普通对象来说,’Map’ 通常更适用于需要高度可变性的场景

Map对象

创建一个Map:

1
let myMap = new Map();

插入键值对:

1
2
myMap.set("key1", "value1");
myMap.set("key2", "value2");

获取值:

1
console.log(myMap.get("key1")); // 输出: value1

检查键是否存在:

1
console.log(myMap.has("key1")); // 输出: true

删除键值对:

1
myMap.delete("key1");

获取Map大小:

1
console.log(myMap.size);

迭代Map:

1
2
3
4
5
6
7
8
9
// 使用for...of迭代键值对
for (let [key, value] of myMap) {
console.log(key, value);
}

// 或者使用forEach方法
myMap.forEach((value, key) => {
console.log(key, value);
});

初始化时传入键值对数组:

1
2
3
4
let myMap = new Map([
["key1", "value1"],
["key2", "value2"]
]);

Map对象的键可以是任意数据类型,而不仅仅是字符串。与对象相比,Map提供了更方便的方法来操作键值对,并且保留了键的插入顺序。

Map对象有几个特点需要注意:

  • 键的唯一性: Map 的键是唯一的,不会出现重复的键。如果尝试使用相同的键多次对 Map 进行插入,后续的值会覆盖先前的值;

  • 使用对象作为键: 由于 Map 的键可以是任意数据类型,包括对象,可以更灵活地进行数据存储和检索;

  • 遍历顺序: Map 保持插入顺序,即遍历时会按照元素插入的顺序进行。这是与 Object 不同的地方,Object 不保证属性的顺序;