当前位置: 首页 > news >正文

JavaScript中普通对象和Map对象的区别

在JavaScript中,普通对象({})Map 对象都是用于存储键值对的数据结构,但是他们有一些区别。

1. 键的类型

普通对象: 对象的键必须是字符串或 Symbol 类型。其他类型的值(如数字、布尔值、对象等)会被强制转换为字符串。例如,1 和 “1” 在对象中是同一个键。

Map: Map 允许任何类型的值作为键,包括对象、函数、原始类型等。例如,1 和 “1” 在 Map 中是不同的键。

2. 键的顺序

普通对象: 在ES6之前,对象的键没有特定的顺序。但在现代JavaScript中,对象的字符串键按插入顺序排序,数字键按升序排序,Symbol 键的顺序未定义。
Map: Map 保留键的插入顺序,当你遍历 Map 时,键会按照插入的顺序被访问。

让我们考虑一个带有电话号码的对象:

let codes = {49: "Germany",41: "Switzerland",44: "Great Britain",// ..,1: "USA",
};for (let code in codes) {console.log(code); // 1, 41, 44, 49
}console.log(Object.keys(codes)); //[ '1', '41', '44', '49' ]

不论是in操作符,还是Object.keys,键的顺序是按照整数顺序排列的,同时Object.values,也是对应的key的顺序的

console.log(Object.keys(codes)); //[ '1', '41', '44', '49' ]
console.log(Object.values(codes)); //[ 'USA', 'Switzerland', 'Great Britain', 'Germany' ]

整数属性会被进行排序,其他属性则按照创建的顺序显示。
所谓整数属性 指的是一个可以在不做任何更改的情况下与一个整数进行相互转换的字符串。

非整数属性
如果属性名不是整数,那它们就按照创建时的顺序来排序,例如:

let user = {name: "John",surname: "Smith",
};
user.age = 25; // 增加一个// 非整数属性是按照创建的顺序来排列的
for (let prop in user) {console.log(prop); // name, surname, age
}
console.log(Object.keys(user)); //[ 'name', 'surname', 'age' ]

两者都有
既有整数属性也有非整数属性

let user = {name: "John",surname: "Smith",49: "Germany",41: "Switzerland",44: "Great Britain",1: "USA",
};
user.age = 25; // 增加一个
user["0"] = 23; // 增加一个// 既有整数属性也有非整数属性
// 1.整数属性会按照数字顺序排序,
// 2.非整数熟悉按照插入顺序
// 3.先输出的是整数属性
for (let prop in user) {console.log(prop); // 0,1,41,44,49,name, surname, age
}
console.log(Object.keys(user)); //[ '0', '1', '41', '44', '49', 'name', 'surname', 'age' ]
3.默认键

普通对象:普通对象继承自 Object.prototype,因此默认带有一些预定义的键(如 toStringhasOwnProperty)。虽然这些键可以被覆盖,但在使用时需要注意可能的冲突

  const obj = { age: 20 };obj.__proto__.test = "haha";for (const k in obj) {console.log(k);/* age 自身的test  和原型对象的可枚举键*/}console.log(Object.keys(obj)); // ['age']console.log(Object.getPrototypeOf(obj));

在这里插入图片描述

注意:

for…in 循环只会迭代可枚举的非符号属性。从内置构造函数(如 Array 和 Object)创建的对象会从Array.prototype 和 Object.prototype 继承不可枚举属性,例如 Array 的 indexOf() 方法或Object 的 toString() 方法,它们在 for…in 循环中不会被访问到。

Map:Map 默认不包含任何键。它只包含显式存入的键值对。因此,Map 对象不会与任何原型链上的属性冲突。

      const map = new Map();map.set("name", "zs"); //自有键map.set("age", 20); //自有键Object.getPrototypeOf(map).test = "haha"; //原型对象的键console.log(map.keys()); //MapIterator {'name', 'age'}
4.迭代性

普通对象:迭代对象的键需要使用 Object.keys()、Object.values()Object.entries()。对象本身并不是可迭代的(没有实现 Symbol.iterator 接口)。for...in也可以遍历对象

for…in 不能直接遍历 Map 对象。它通常用于遍历普通对象的属性,而不是 Map 对象的键值对。

      const map = new Map();map.set("name", "zs"); //自有键map.set("age", 20); //自有键for (const key in map) {console.log(key); //没有任何输出}

要遍历 Map 对象,map是可迭代的,使用for...of或者

map.forEach() / map.keys() / map.values() / map.entries()
5.序列化

普通对象:对象可以使用 JSON.stringify() 进行序列化,结果是一个JSON字符串。
Map:Map 不能直接通过 JSON.stringify() 进行序列化,因为它不是一个普通的对象。如果需要序列化 Map,需要先将其转换为数组或对象。

普通对象的序列化

      const obj = {name: "Alice",age: 30,city: "New York",};const jsonString = JSON.stringify(obj);console.log(jsonString); // {"name":"Alice","age":30,"city":"New York"}

Map 对象的序列化
Map 对象不能直接用 JSON.stringify() 进行序列化。如果你尝试这样做,结果会是一个空对象 {}

      const map = new Map();map.set("name", "Alice");map.set("age", 30);map.set("city", "New York");const jsonString = JSON.stringify(map);console.log(jsonString); // {}

为了正确序列化 Map 对象,你需要先将 Map 转换为可以被 JSON.stringify() 识别的格式,如数组或对象。

转换为普通对象

const map = new Map();
map.set("name", "Alice");
map.set("age", 30);
map.set("city", "New York");const mapObject = Object.fromEntries(map);
const jsonStringFromObject = JSON.stringify(mapObject);
console.log(jsonStringFromObject); // {"name":"Alice","age":30,"city":"New York"}

反序列化
对于 Map 对象,先将 JSON 字符串转换为数组或对象,再转换为 Map。

const map = new Map();
map.set("name", "Alice");
map.set("age", 30);
map.set("city", "New York");// 序列化
const mapObject = Object.fromEntries(map);
const jsonStringFromObject = JSON.stringify(mapObject);
console.log(jsonStringFromObject); // {"name":"Alice","age":30,"city":"New York"}// 反序列化
// 1.先将 JSON 字符串转换为数组或对象
const parsedObject = JSON.parse(jsonStringFromObject);
// 2.再转换为 Map
const parsedMapFromObject = new Map(Object.entries(parsedObject));
console.log(parsedMapFromObject.get("name")); // "Alice"

6.使用场景

普通对象:适用于管理少量数据,并且键是已知的、简单的字符串或符号的情况下。
Map:适用于需要灵活、动态键(特别是非字符串键),或者需要高效查找和操作大量键值对的场景。

相关文章:

JavaScript中普通对象和Map对象的区别

在JavaScript中,普通对象({})和 Map 对象都是用于存储键值对的数据结构,但是他们有一些区别。 1. 键的类型 普通对象: 对象的键必须是字符串或 Symbol 类型。其他类型的值(如数字、布尔值、对象等&#x…...

Liunx搭建Rustdesk远程桌面服务

1、环境准备 Linux:centos7.9 rustdesk server安装包 很多新服务器并没有 wget 和unzip 可以通过yum自行安装下,如果系统中有wget但不能使用,直接卸载重装即可。 yum install wget wget --no-check-certificate https://github.com/rust…...

antv X6--实现节点旁添加多个text标签

前言:接本专栏上篇文章,实现一个新需求,如有不懂的可先去看新手教程 需求描述:如何在节点旁添加多个标签,如下图所示: 实现该需求目前我只想到两种方法: 方法一:使用换行符将不同的…...

JAVA--多线程

Java中的多线程是指在同一个Java虚拟机(JVM)中并发执行多个线程的能力。线程是程序执行的最小单元,Java提供了丰富的API来创建和管理线程。以下是Java中实现多线程的一些关键概念和方法: Thread 类:Java提供了Thread类…...

ADB-DROM

# 读硬件信息 adb shell "cat /sys/block/mmcblk0/device/name" # MT6767/MT6768/MT6769/MT6762/MT6765/MT6761... # 频率档位 # 固定频率 adb shell "echo 0 > /sys/devices/platform/10012000.dvfsrc/helio-dvfsrc/dvfsrc_force_vcore_dvfs_opp" # …...

mysql 之 explain

1. 查看表的创建字段以及索引情况 show create table user_recommend; 2. 创建索引的原则:列的值比较离散 像性别字段,只有男,女 或者其他;expose字段,只有1分发,0不可分发。就不适宜在这种字段上添加索引…...

CentOS迁移案例 | 保障轨道交通安全、发挥基础设施效能,麒麟信安操作系统支撑某市轨道交通畅行无忧

为缓解城市交通拥堵难题,某市轨道交通公司计划新建一条贯穿城市关键区域、沿路设立20座站点的轨道交通线路,并基于麒麟信安操作系统构建轨道交通信号系统。 轨道交通信号系统是列车核心控制系统,负责列车运行的自动化控制,及对整…...

获取操作系统的信息(Go语言)

在 Go 语言中,你可以使用 runtime 和 os 包来查看操作系统的信息。以下是一些常见的操作系统信息获取方法: 1. 获取操作系统类型和架构信息 Go 的 runtime 包提供了基本的操作系统和架构信息: package mainimport ("fmt""r…...

【论文阅读】HuatuoGPT-II, One-stage Training for Medical Adaption of LLMs

总体概要 本文深入探讨了一款专为医疗领域设计的大规模语言模型——HuatuoGPT-II的创新、性能与应用。HuatuoGPT-II采用统一的单阶段训练流程,将传统的继续预训练和监督微调整合,有效解决了医疗数据的异质性问题,包括语言、体裁和格式差异&a…...

Excel表列序号

题目 给定一个Excel表格中的列名称,返回其相应的列序号。 例如, A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 ...示例 1: 输入: "A" 输出: 1示例 2: 输入: "AB" 输出: 28示例 3: 输入: "ZY&…...

IOS 03 纯代码封装自定义View控件

本节将通过纯代码进行封装自定义View控件,以常用的设置页的item为例,实现UI效果如下: 1、创建SettingView继承自UIView import UIKitclass SettingView: UIView {} 2、重写 init() 和 required init?(coder: NSCoder) 方法 纯代码创建Set…...

比较结构加法及其逆运算

在行列可自由变换的平面上有等式 13(3a11)2*4a14a22*4a32*4a44*4a122*4a14 3a11在平面上可能得到6个不同的4点结构,这6个结构的比例为2:1:2:2:4:2. 现在从右向左算,计…...

44.【C语言】指针(重难点)(G)

目录 19.字符指针变量 *定义 *简单说明 *如果是字符串 *像数组一样指定访问常量字符串的字符 *练习 20.数组指针变量 *定义 *格式 *例子 问题1 问题2 *利用指针打印 21.二维数组传参的本质 *回顾 往期推荐 19.字符指针变量 *定义 指向字符的指针变量,用于存储字符…...

746. 使用最小花费爬楼梯-dp3

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/min-cost-climbing-stairs/description/从左向右填dp表 class Solutio…...

MPU6050详细介绍

一、MPU6050介绍 MPU6050是由三个陀螺仪和三个加速度传感器组成的6轴运动处理组件 内部主要结构:陀螺仪、加速度计、数字运动处理器DMP(Digital Motion Processor) MPU6050有两个IIC接口,第一IIC接口可作为主接口给单片机传输数…...

【分享】Excel的3个隐藏功能

我们在制作Excel表格的时候,有时候会包含一些敏感信息,为了确保这些数据的安全性,Excel提供了隐藏功能来保护工作表,下面小编分享3个Excel常用的隐藏功能,一起来看看如何设置吧! 功能一:隐藏部分…...

Linux中的chown指令

chown(change owner)命令在 Linux 和其他类 Unix 系统中用于更改文件或目录的用户和/或组所有权。 基本用法 chown [选项] 用户名[:组名] 文件或目录 参数说明 用户名:指定新的文件或目录的所有者 组名:可选,指定新…...

UCOSIII内存管理机制详解

目录 前言 1. 内存管理概述 2. 内存区域(存储区)和内存块 3. 存储区控制块(OS_MEM) 4. 内存管理函数 5. 内存碎片问题 6. 注意事项 7.代码实现 7.1创建内存区域 7.2申请内存 7.3释放内存 前言 UCOSIII(即Mi…...

Android12 显示框架之Transaction----client端

目录:Android显示终极宝典 在前面的章节中,应用通过createSurface()在surfaceflinger中创建了一层layer,紧接着要做的事情就是对这个layer设置一些属性(或者叫状态),常设置的属性有位置、大小、z-order等等…...

在Windows上使用FRP搭建内网穿透:

FRP服务器端配置&#xff08;公网服务器&#xff09; 下载FRP&#xff1a; 访问FRP的GitHub发布页面&#xff1a;https://github.com/fatedier/frp/releases下载对应系统架构的frp_<version>_linux_amd64.tar.gz&#xff08;如果你的服务器是Linux系统&#xff09;或者f…...

TypeError: Cannot read properties of undefined (reading ‘scrollIntoView‘)(已解决)

问题复现&#xff1a;眨眼睛使用vitevue3实现跳转dom功能时使用了scrollIntoView方法&#xff0c;在打包上传以后使用该功能报错 小友可能会陷入误区&#xff0c;以为是函数方法有问题&#xff0c;毕竟在开发时是没有问题的&#xff0c; 而实际上呢问题出在获取节点失败了 在这…...

【解决】Unity Inspector 视窗脚本中文乱码问题

开发平台&#xff1a;Unity 2020 编程平台&#xff1a;Visual Studio 2022   问题描述 开发过程中&#xff0c;为便利化快速审阅代码内容&#xff0c;通过 Unity Inspector 确认代码内容与逻辑。但对于默认安装的 Visual Studio 编程平台&#xff0c;保存的 UTF- 8 脚本文件在…...

使用 C/C++访问 MySQL

目录 准备工作 尝试链接 MySQL Client MySQL 接口介绍 准备工作 保证 MySQL 服务有效。下载MySQL开发包&#xff08;可以在MySQL官网下载安装也可以在软件源安装&#xff09; MySQL 开发包通常会包含一些特定的头文件和库文件。您可以检查以下常见的路径&#xff1a; /us…...

Linux 网络套接字解析:实现网络通信

目录 一.网络基础1.协议2.OSI与TCP/IP模型3.网络通信流程4.IP与Mac地址 二.网络编程套接字1.端口号2.网络字节序3.tcp、udp协议4.socket编程5.sockaddr结构解析6.实现Udp_socket7.实现Windows与Linux通信8.Linux下远程执行指令9.实现tcp_socket10.守护进程 一.网络基础 1.协议…...

vue3 组合式API

<!-- 深度监听 deep 点击按钮控制台&#xff0c;才输出count变化了: 1, 老值: 0;否则控制台不输出 --> <script setup>import { ref,watch } from vueconst state ref({count:0})const setCount () > {state.count.value}watch(state, () > {console.log(…...

二、什么是Vue中的响应式?Vue的响应式原理

什么是Vue中的响应式 Vue中的响应式&#xff0c;简而言之就是当数据发生变化时&#xff0c;页面跟随变化。使用过Vue的v-model都有比较深刻的感受&#xff0c;我们在代码中修改双向绑定的数据后&#xff0c;页面上的数据也会自动更新&#xff0c;页面跟随变化 我们看个例子&am…...

快9月了才开始强化,跟张宇还是武忠祥?

快9月了才开始强化&#xff0c;跟张宇还是武忠祥&#xff01; 说真的&#xff0c;我也替这位同学着急&#xff0c;但是考研数学越是进度慢&#xff0c;就越不能急&#xff01;急着赶进度&#xff0c;容易出事&#xff01;遇到这个问题的朋友肯定不止一位&#xff0c;那我就帮大…...

SSM好易学学习平台---附源码92142

摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xff0c;采用Java技术建设好易学学习平台。本文…...

对于mp4 ios和mac safari不能播放问题处理

直接对原mp4文件进行重新转码就可以了 ffmpeg -i origin.mp4 -vcodec h264 -profile:v high -level 4.1 orgin_hl.mp4 原因源文件不符合苹果基本规则 苹果官网文档...

开发同城交友找搭子系统app前景分析

开发同城交友系统APP的背景 社交需求多样化&#xff1a; 随着城市化的加速和人们生活节奏的加快&#xff0c;现代人的社交圈子往往较为狭窄&#xff0c;难以结识新朋友。传统的线下交友方式受限于时间、地点等因素&#xff0c;难以满足现代人对于交友的多样化需求。互联网和智…...

faiss向量数据库测试《三体》全集,这家国产AI加速卡,把性能提了7倍!

在人工智能和机器学习技术的飞速发展中&#xff0c;向量数据库在处理高维数据方面扮演着日益重要的角色。近年来&#xff0c;随着大型模型的流行&#xff0c;向量数据库技术也得到了进一步的发展和完善。 向量数据库为大型模型提供了一个高效的数据管理和检索平台&#xff0c;…...

负载均衡---相关概念介绍(一)

负载均衡&#xff08;Load Balance&#xff09;是集群技术的一种重要应用&#xff0c;旨在将负载&#xff08;工作任务&#xff09;进行平衡、分摊到多个操作单元上进行运行&#xff0c;从而提高系统的并发处理能力、增加吞吐量、加强网络处理能力&#xff0c;并提供故障转移以…...

计算机基础知识复习8.14

子线程抛异常主线程能否catch 在不做任何处理的情况下&#xff0c;主线程不能catch 解决方式&#xff1a; 子线程使用try catch来捕获异常 为线程设置未捕获异常处理器UncaughtExceptionHandler 通过future的get方法捕获异常 JVM相关参数 显示指定堆内存-Xms和-Xmx指定最…...

【io深层理解】

io深层理解 1.内核态2.用户态3. select IO多路复用执行原理4. select io多路复用限制和不足 1.内核态 一个进程会涉及多文件的修改&#xff0c;比如说。那么在内核态就会维护一个表&#xff0c;这个表叫文件描述符bitmap&#xff0c;这个表会传递给内核态&#xff0c;当然肯定传…...

【懒人工具】指定新文件,替换全盘旧文件

没辙&#xff0c;就是懒 最近在调整.clang-format&#xff0c;这个format文件要跟着项目走&#xff0c;只换本地默认的还不够。调整好以后一个项目一个项目的换&#xff0c;有时候会漏掉&#xff0c;索性全盘一次性换完。 基于自己操作的流程&#xff0c;写了个脚本&#xff0…...

React+Vis.js(02):设置节点样式

文章目录 1、修改vis.js的节点和关系颜色2、修改vis.js节点的字体颜色2.1 统一设置节点字体颜色2.2 自定义某个节点的字体颜色3、设置vis.js节点的边框颜色和宽度3.1 设置单个节点3.2 统一设置1、修改vis.js的节点和关系颜色 在vis.js中,可以通过color属性,来给node节点添加…...

3G网络要彻底没了

2月21日,三大运营商公布了最新的用户数据,移动联通电信三家5G套餐用户数合计超过了7.5亿。信通院早前公布的数据显示,一月份,国内市场5G手机出货量2632.4万部,占同期手机出货量的79.7%。 这两项数据,说明我们已经进入到了5G时代,5G的普及速度远超很多人的想象。就在5G逐…...

如何配置ESXI主机的IP地址管理

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作…...

软件测试学习笔记丨测试用例设计方法

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/31921 一&#xff0c;黑盒测试方法论 1&#xff0c;等价类 1.1 定义 等价类划分是一种重要的、常用的黑盒测试方法不需要考虑程序的内部结构&#xff0c;只需要考虑程序的输入规格即可它将…...

MinIO基本用法

在现代云计算和大数据领域&#xff0c;对象存储因其可扩展性、可靠性和低成本成为数据存储的重要选择。MinIO作为一个高性能、分布式的对象存储系统&#xff0c;凭借其开源、简单易用以及与Amazon S3兼容的特性&#xff0c;在业界得到了广泛的应用。本文将带您了解MinIO的基本用…...

MySQL windows版本安装

一、下载MySQL安装包 访问MySQL官网&#xff1a;首先&#xff0c;访问MySQL的官方网站&#xff08;MySQL&#xff09;&#xff0c;或者更具体地&#xff0c;访问MySQL的下载页面&#xff08;MySQL :: Download MySQL Community Server&#xff09;。 选择适合的版本&#xff1…...

Python实现人脸轮廓提取

目录 一、背景知识1.1 人脸检测和轮廓提取的意义1.2 人脸检测方法概述1.3 轮廓提取方法概述二、常用的人脸轮廓提取方法2.1 基于边缘检测的轮廓提取2.2 基于形态学操作的轮廓提取2.3 基于特征点检测的轮廓提取三、Python实现人脸轮廓提取3.1 安装依赖库3.2 使用Dlib进行人脸检测…...

Prettier+Vscode setting提高前端开发效率

文章目录 前言Prettier第一步&#xff1a;下载依赖&#xff08;团队合作&#xff09;或下载插件&#xff08;独立开发&#xff09;第二步&#xff1a;添加.prettierrc.json文件**以下是我使用的****配置规则** 第三步&#xff1a;添加.prettierignore文件**以下是我常用的****配…...

YOLOv10实时端到端目标检测

文章目录 前言一、非极值大抑制(NMS)二、NMS算法的具体原理和步骤三、YOLOV10创新点四、YOLOv10使用教程五、官方github地址 前言 距离上次写YOLOv5已经过去了两年&#xff0c;正好最近用YOLOv10重构了项目&#xff0c;总结下YOLOv10。 YOLOv10真正实时端到端目标检测&#xff…...

Java中的Annotation注解

常用注解 override&#xff1a;重写方法deprecated&#xff1a;弃用SuppressWarnings&#xff1a;抑制编译器警告 元注解&#xff08;注解的注解&#xff09; Target&#xff1a;描述注解所能修饰的类型Retention&#xff1a;描述注解的生命周期&#xff08;SOURCE源代码、C…...

小五金加工:细节决定产品质量与性能

在小五金加工领域&#xff0c;细节往往决定着最终产品的质量、性能以及市场竞争力。看似微不足道的细微之处&#xff0c;实际上蕴含着巨大的影响。时利和将介绍小五金加工中细节的重要性。 首先&#xff0c;细节关乎产品的精度。小五金零件通常尺寸较小&#xff0c;但对精度的要…...

VS Code安装配置ssh服务结合内网穿透远程连接本地服务器详细步骤

文章目录 前言1. 安装OpenSSH2.VS Code配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…...

世界首位「AI科学家」问世!独立生成10篇学术论文! 横扫「顶会」?

大家好&#xff0c;我是 Bob! &#x1f60a; 一个想和大家慢慢变富的 AI 程序员&#x1f4b8; 分享 AI 前沿技术、项目经验、面试技巧! 欢迎关注我&#xff0c;一起探索&#xff0c;一起破圈&#xff01;&#x1f4aa; AI科学家出世 最近一位人工智能AI科学家横空出世。 它是…...

【高阶数据结构】图

图 1. 图的基本概念2. 图的存储结构2.1 邻接矩阵2.2 邻接表2.3 邻接矩阵的实现2.4 邻接表的实现 3. 图的遍历3.1 图的广度优先遍历3.2 图的深度优先遍历 4. 最小生成树4.1 Kruskal算法4.2 Prim算法 5. 最短路径5.1 单源最短路径--Dijkstra算法5.2 单源最短路径--Bellman-Ford算…...

调研-音视频

音视频 基础概念主要内容音频基础概念音频量化过程音频压缩技术视频基础概念视频bug视频编码H264视频像素格式YUVRGB参考文献基础概念 ● 实时音视频应用环节 ○ 采集、编码、前后处理、传输、解码、缓冲、渲染等很多环节。 主要内容 音频 基础概念 三要素:音调(音频)、…...