Object、Map 与 Set 的异同分析
一、共同点
-
数据存储:三者均用于存储数据,但数据组织形式不同:
-
Object :以键值对(
key-value
)形式存储数据,但键仅限字符串或 Symbol。 -
Map:以键值对形式存储数据,键可以是任意类型(对象、函数等) 。
-
Set:以唯一值的集合形式存储数据,类似数组但无重复元素 。
-
-
键的唯一性:三者均保证键的唯一性:
-
Object 的键若重复,后者覆盖前者。
-
Map 的键若重复,后者覆盖前者。
-
Set 的值若重复,自动去重。
-
1. Object 与 Map 的对比
维度 | Object | Map |
---|---|---|
键类型 | 仅支持字符串或 Symbol15 | 支持任意类型(对象、函数等)15 |
键顺序 | ES6 前无序;ES6 后部分有序(整数属性优先)7 | 严格按插入顺序存储5 |
遍历能力 | 需通过 Object.keys() 等转换后遍历6 |
原生支持 keys() 、values() 、entries() 5 |
内存管理 | 强引用,可能导致内存泄漏 | 可通过 WeakMap 实现弱引用,自动回收无引用键38 |
API 方法 | 无内置方法,需手动操作(如 delete ) |
提供 set() 、get() 、has() 等链式操作15 |
示例代码
js
// Object 键类型限制
const obj = { 1: "a", "1": "b" };
console.log(obj); // { '1': 'b' },键被强制转为字符串
// Map 支持任意键类型
const map = new Map();
map.set({}, "对象键").set(1, "数字键");
console.log(map.get(1)); // "数字键"
2. Map 与 Set 的对比
维度 | Map | Set |
---|---|---|
数据结构 | 键值对(key-value ) |
单值集合(value ) |
去重机制 | 键唯一,值可重复 | 值唯一,自动去重 |
应用场景 | 需关联复杂键的场景(如 DOM 节点元数据) | 数组去重、集合运算(交并补) |
示例代码
js
// Set 自动去重
const arr = [1, 2, 2, 3];
const uniqueArr = [...new Set(arr)]; // [1, 2, 3]
// Map 关联复杂键
const domMap = new Map();
const element = document.getElementById("app");
domMap.set(element, { clicks: 0 });
3. Object 与 Set 的对比
维度 | Object | Set |
---|---|---|
存储形式 | 键值对 | 单值集合 |
键值关系 | 键与值独立(key 和 value 无关联) |
值即键([value, value] ) |
性能 | 频繁增删时效率较低(需维护原型链) | 增删查效率高(基于哈希表或红黑树) |
三、应用场景总结
-
Object
-
简单键值存储(如配置对象)。
-
需利用原型链继承的场景。
-
-
Map
-
键类型复杂的场景(如对象关联元数据)。
-
需严格维护插入顺序的场景(如日志记录)。
-
-
Set
-
数组去重、集合运算。
-
临时存储唯一值(如用户 ID 缓存)。
-
四、选型建议
-
优先用 Map:当需要非字符串键、频繁增删键值对时。
-
优先用 Set:当需快速去重或集合运算时。
-
保留 Object:在简单数据存储或需利用 JSON 序列化时。
CMD 与 ESM 的核心区别(JavaScript 模块化对比)
1. 模块定义与语法
-
CMD (Common Module Definition)
语法基于
define
函数,依赖就近声明,延迟执行。javascript// 模块定义 define(function(require, exports, module) { const a = require('./a'); // 依赖就近引入 exports.result = a.value * 2; });
特点:依赖在代码执行时动态加载,适合浏览器端 。
-
ESM (ECMAScript Modules)
使用
import
和export
关键字,依赖静态声明,编译时确定关系。javascript// 模块导出 export const value = 10; // 模块导入 import { value } from './a.js';
特点:依赖在代码解析阶段确定,支持静态分析和编译优化(如 Tree Shaking)。
2. 加载机制
-
CMD
-
动态加载:运行时按需加载模块,通过回调函数处理依赖。
-
延迟执行 :模块代码在第一次被
require
时执行,适合浏览器异步环境。 -
示例:Sea.js 实现中,模块只有在被引用时才会加载和执行。
-
-
ESM
-
静态加载:模块依赖在编译时解析,支持预加载和并行加载。
-
顶层作用域 :
import
必须写在模块顶层,不能在条件语句中使用,确保依赖关系明确。
-
3. 值的传递方式
-
CMD
- 值拷贝:导出的是值的拷贝,模块内部修改不会影响外部引用。
javascript// a.js let count = 1; setTimeout(() => { count = 2 }, 1000); module.exports = { count }; // b.js const { count } = require('./a'); console.log(count); // 1(即使 a.js 中的 count 后续变为 2)
适用场景:简单数据导出,但无法实现动态响应。
-
ESM
- 值引用:导出的是值的引用,模块内部修改会同步到外部。
javascript// a.js export let count = 1; setTimeout(() => { count = 2 }, 1000); // b.js import { count } from './a.js'; setTimeout(() => console.log(count), 2000); // 2
优势:适合状态共享和响应式编程(如 React 状态管理)。
4. 作用域与执行环境
-
CMD
-
函数作用域 :模块代码包裹在
define
函数中,变量隔离依赖闭包。 -
运行时污染风险:若模块未正确封装,可能污染全局变量 。
-
-
ESM
-
模块作用域:每个模块拥有独立作用域,变量默认不泄露到全局。
-
严格模式:默认启用严格模式(如禁止未声明变量)。
-
5. 生态系统与兼容性
-
CMD
-
浏览器优先:设计初衷为解决浏览器端模块化(如 Sea.js),依赖加载器(如 RequireJS)。
-
旧项目兼容:适用于遗留系统或需动态加载的场景,但逐渐被现代标准淘汰 。
-
-
ESM
-
原生支持:现代浏览器和 Node.js(v12+)均原生支持,无需第三方库。
-
未来主流:成为前端构建工具(Webpack、Rollup)的默认标准,支持跨环境统一。
-
GET和POST的请求区别
GET和POST是HTTP协议中最常用的两种请求方法。它们在数据传输方式、安全性、缓存等方面存在显著差异。
-
数据传输方式
- get :GET 请求将参数直接附加在 URL 后面,参数和值通过 ? 和 & 连接,例如:/admin/index.html?name1=value1&age=value2
- post:POST 请求则将参数放在 HTTP 消息主体中,不显示在 URL 中。
-
安全性
- get:GET 请求的参数暴露在 URL 中,容易被第三方截获,不适合传输敏感信息。
- post:POST 请求的参数放在消息主体中,相对更安全。
-
数据长度限制:
- get:GET 请求的 URL 长度有限制,一般不超过 2048 个字符。
- get:POST 请求没有长度限制,可以传输大量数据。
-
缓存和历史记录:
- get:GET 请求可以被缓存,参数会保留在浏览器历史记录中,可以收藏为书签。
- post:POST 请求不会被缓存,参数也不会保留在历史记录中,不能收藏为书签。
-
编码类型:
- get :GET 请求只能进行 URL 编码(application/x-www-form-urlencoded),
- post :POST 请求支持多种编码方式,包括 multipart/form-data。
-
TCP 数据包:
- get:GET 请求通常产生一个 TCP 数据包,
- post:POST 请求则需要两个 TCP 数据包:先发送 header,再发送 data。
总的来说,GET适用于获取数据,POST适用于提交数据。选择使用哪种方法取决于具体需求和数据的敏感性。
CSS之Flex布局中核心属性及其值的详细解析,
1、容器属性
1. flex-direction
定义主轴方向,控制项目排列顺序:
go
• **`row`**(默认):水平从左到右排列
• **`row-reverse`**:水平从右到左排列
• **`column`**:垂直从上到下排列
• **`column-reverse`**:垂直从下到上排列
2. flex-wrap
控制项目是否换行:
go
• **`nowrap`**(默认):不换行,强制压缩项目宽度
• **`wrap`**:换行,新行从上到下排列
• **`wrap-reverse`**:换行,新行从下到上排列
3. flex-flow
css
`flex-direction` 和 `flex-wrap` 的简写:
• 示例:`flex-flow: column wrap` 表示垂直排列且允许换行
4. justify-content
主轴对齐方式:
go
• **`flex-start`**(默认):左对齐
• **`flex-end`**:右对齐
• **`center`**:居中对齐
• **`space-between`**:两端对齐,项目间距相等
• **`space-around`**:项目两侧间距相等(首尾间距为中间一半)
• **`space-evenly`**:所有间距均等
5. align-items
交叉轴对齐方式:
go
• **`stretch`**(默认):拉伸至容器高度(无固定高度时)
• **`flex-start`**:顶部对齐
• **`flex-end`**:底部对齐
• **`center`**:垂直居中对齐
• **`baseline`**:按项目首行文字基线对齐
6. align-content
多行项目在交叉轴的对齐方式(仅多行生效):
javascript
• **`stretch`**(默认):拉伸占满剩余空间
• **`flex-start`** / **`flex-end`** / **`center`**:对齐方式与 `justify-content` 类似
7. gap
系列 控制项目间距:
go
• **`gap: 10px`**:统一设置行、列间距
• **`row-gap`** / **`column-gap`**:单独设置行或列间距
2、项目属性
1. order
定义项目排列顺序,数值越小越靠前:
markdown
• **默认值**:`0`
• 示例:`order: -1` 将项目提前至首位
2. flex-grow
分配剩余空间的放大比例:
markdown
• **默认值**:`0`(不放大)
• **值 >0**:按比例分配剩余空间(如 `flex-grow: 2` 占双倍空间)
3. flex-shrink
空间不足时的缩小比例:
markdown
• **默认值**:`1`(等比缩小)
• **值 0**:禁止缩小(保持原始宽度)
4. flex-basis
项目初始主轴尺寸:
markdown
• **默认值**:`auto`(基于内容或固定宽高)
• **固定值**:`300px` 或 `50%` 等
5. flex
简写属性:flex-grow
+ flex-shrink
+ flex-basis
:
less
• **`flex: 1`**:等价于 `1 1 0%`(占满剩余空间)
• **`flex: 0`**:等价于 `0 1 auto`(不放大,仅允许缩小)
• **`flex: none`**:等价于 `0 0 auto`(禁止伸缩)
6. align-self
单个项目在交叉轴的对齐方式:
javascript
• **`auto`**(默认):继承容器 `align-items`
• **`flex-start`** / **`flex-end`** / **`center`**:覆盖容器对齐方式
3、关键应用场景
-
居中布局 :
css.container { display: flex; justify-content: center; align-items: center; }
-
等分空间 :
css.item { flex: 1; } /* 所有项目平分容器宽度 */
-
响应式换行 :
css.container { flex-wrap: wrap; }
4、注意事项
• 兼容性 :Flex 布局兼容现代浏览器,但 IE 11 需要前缀 -ms-
• 优先级 :项目属性(如 flex
)会覆盖容器属性(如 align-items
)
通过灵活组合这些属性,可以快速实现复杂布局需求。如需更详细示例,可参考 中的完整代码片段。
清除浮动的常见三种方法及示例,结合不同场景和兼容性需求进行总结:
1、伪元素清除法(推荐)
原理 :利用 ::after
伪元素在父级末尾插入内容并清除浮动。
示例:
css
.clearfix::after {
content: "";
display: block; /* 或 table */
clear: both;
}
.clearfix {
zoom: 1; /* 兼容 IE6-7 */
}
优点:
-
无额外 HTML 标签,语义化好。
-
兼容性较好(通过
zoom:1
支持旧版 IE)。
缺点:
- 需理解伪元素和
clear
属性的作用。
###@ 2、空标签清除法
原理 :在浮动元素后添加空标签并设置 clear:both
。
示例:
html
<div class="parent">
<div class="float-left"></div>
<div class="float-right"></div>
<div style="clear: both;"></div> <!-- 空标签 -->
</div>
优点:
- 实现简单,适合快速修复。
缺点:
- 增加无意义标签,破坏 HTML 结构。
3、父级触发 BFC
方法 :通过 CSS 属性触发 BFC(块级格式化上下文),自动包含浮动元素。
示例:
css
.parent {
overflow: hidden; /* 或 auto */
/* display: flow-root; */ /* 现代方案,无副作用[4,9](@ref) */
}
优点:
- 代码简洁,无需额外标签 。
缺点:
-
overflow: hidden
可能导致内容裁剪或滚动条 。 -
display: flow-root
不兼容 IE11。
以下是 CSS 实现水平居中对齐的常用方法
1. 行内元素/行内块元素
方法 :父容器设置 text-align: center
原理:通过文本对齐属性控制行内元素的水平位置。
示例:
css
.parent {
text-align: center; /* 父级设置 */
}
.child {
display: inline-block; /* 子元素转为行内块 */
}
适用场景:文本、按钮、图片等行内元素。
2. 块级元素(已知宽度)
方法 :子元素设置 margin: 0 auto
原理:通过自动计算左右外边距实现居中,需明确子元素宽度。
示例:
css
.child {
width: 200px; /* 必须指定宽度 */
margin-left: auto;
margin-right: auto;
}
注意:若父容器未指定宽度或子元素未设置宽度,此方法无效。
3. Flex 布局
方法 :父容器设置 display: flex
+ justify-content: center
原理:通过弹性盒模型的主轴对齐属性控制居中。
示例:
css
.parent {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center;
}
优势:支持复杂布局,无需子元素设置宽度。
4. Grid 布局
方法 :父容器设置 display: grid
+ place-items: center
原理:网格布局同时控制水平和垂直对齐。
示例:
css
.parent {
display: grid;
place-items: center; /* 简写属性 */
// place-items属性是justify-items(水平)和 align-items(垂直)的简写
}
适用场景:现代浏览器项目,代码简洁高效。
5. 绝对定位 + 平移
方法 :子元素绝对定位后,通过 left: 50%
+ transform
调整
原理:基于父容器的 50% 位置反向平移实现居中。
示例:
css
.parent {
position: relative; /* 父级相对定位 */
}
.child {
position: absolute;
left: 50%; /* 定位到中间 */
top: 50%;
transform: translate(-50%,-50%); //或者margin设置-值
}
优势:适合未知宽度的元素。
6. 表格布局(传统方法)
方法 :父容器设置 display: table-cell
+ text-align: center
示例:
css
.parent {
display: table-cell; /* 模拟表格单元格 */
text-align: center;
}
缺点:性能较差,逐渐被 Flex/Grid 替代。
总结与选择建议
• 优先现代布局:Flex 和 Grid 语法简洁,兼容性好(需注意 IE 等旧浏览器)。
• 行内元素 :直接用 text-align: center
,无需复杂设置。
• 固定宽度块元素 :margin: 0 auto
快速实现。
• 未知宽度元素:绝对定位 + 平移或 Flex/Grid 更灵活。
可根据具体需求选择最合适的方法,更多细节可参考上述来源中的完整代码示例。