web前端知识点总结2026二1. foreach不能break的原理2. http1.1 一次tcp连接最多支持多少http请求3. 针对单个文件上传如何知道上传进度4. Webpack 分块Code Splitting核心原理5. 前端 resolve路径解析模式 方法6. 移动端适配的方式6. 前端动画实现方式7. JavaScript 如何判断可迭代对象1. foreach不能break的原理forEach 不是循环语法它是数组的方法 回调函数机制语法层面就不支持 break。详细原理1、本质不同for/for…of 是JS 原生循环语句语法上天生支持 break、continueforEach 是数组对象的一个方法它内部封装了循环逻辑你写的代码是在回调函数里不是在循环体里。2、作用域不匹配break 只能跳出当前所在的循环语句但你的回调函数是一个独立函数不在循环语句的作用域内。你在 forEach 回调里写 breakJS 根本找不到它属于哪个循环直接报错。3、设计初衷forEach 被设计出来的目的就是遍历数组的每一项必须全部执行完不允许中途中断。它的设计理念就是 “完整遍历”没有提供中断能力。总结forEach 是方法 回调函数不是循环语句break 是循环专用关键字只能在 for/while 等循环里用回调函数和循环不在同一个作用域语法不支持所以无法 break2. http1.1 一次tcp连接最多支持多少http请求HTTP/1.1 单个 TCP 连接本身可以发无数个请求长连接。浏览器限制同一域名最多 6 个并发 TCP 连接。超过 6 个请求会排队不会同时发。3. 针对单个文件上传如何知道上传进度前端上传文件时浏览器的网络请求对象XMLHttpRequest/fetch会触发上传进度事件事件对象会返回两个关键值loaded已经上传的字节数total文件总字节数通过 (loaded / total) * 100 就能计算出上传进度百分比。!DOCTYPEhtmlhtmlheadtitle文件上传进度/titlestyle.progress-bar{width:300px;height:10px;background:#eee;margin:10px0;}.progress{height:100%;background:#409eff;width:0%;transition:width0.2s;}/style/headbodyinput typefileidfileInput/divclassprogress-bardivclassprogressidprogress/div/divp idprogressText0%/pscriptconstfileInputdocument.getElementById(fileInput);constprogressBardocument.getElementById(progress);constprogressTextdocument.getElementById(progressText);// 选择文件后自动上传fileInput.addEventListener(change,(e){constfilee.target.files[0];if(!file)return;// 1. 创建请求对象constxhrnewXMLHttpRequest();// 2. 配置上传接口xhr.open(POST,/upload);// 替换为你的后端上传接口// 核心监听上传进度事件xhr.upload.addEventListener(progress,(event){if(event.lengthComputable){// 判断文件大小是否可计算// 计算进度百分比constpercent(event.loaded/event.total)*100;// 更新进度条和文字progressBar.style.widthpercent%;progressText.textContentpercent.toFixed(2)%;}});// 上传完成xhr.onload(){if(xhr.status200){progressText.textContent上传完成;}};// 3. 构建表单数据上传文件constformDatanewFormData();formData.append(file,file);// file 为后端接收的参数名// 4. 发送请求xhr.send(formData);});/script/body/html4. Webpack 分块Code Splitting核心原理1 分块分的是什么分的是 chunk代码块不是依赖依赖 你的代码文件、第三方库如 vue/react/lodashchunk Webpack 打包后生成的独立 JS 文件就是最终输出的 app.js、vendors~app.js 这种分块的本质把一堆依赖打包成若干个独立 chunk 文件而不是全部塞进一个大文件里。2分块是根据什么来分的核心规则Webpack 分块只有 3 大依据所有分块逻辑都源于此① 入口起点entry—— 最基础的分块你配置几个 entry就自动生成几个初始 chunk。entry:{home:./src/home.js,// 生成 home chunkadmin:./src/admin.js// 生成 admin chunk}✅ 依据多页面 / 多入口分离② 动态导入import ()—— 按需加载import(./DetailPage).then(module{...})Webpack 自动把 DetailPage 切成独立 chunk。✅ 依据用户不需要一开始就加载的代码路由、弹窗、懒加载模块1按需引入到底是什么不是只引入部分代码而是 “需要时才加载整个文件 / 模块”常规引入页面一打开所有代码一次性下载、执行按需引入页面打开只加载核心代码点按钮 / 切路由时再去下载额外的 JS 文件2按需引入的完整底层逻辑4 步1. 构建阶段Webpack 自动拆包你写一行动态导入// 你的代码constDialogimport(./Dialog.js)Webpack 背后做的事识别到 import() → 把 Dialog.js 单独切成一个独立 chunk比如 async_Dialog.js给这个 chunk 生成一个唯一标识主包里不包含这个文件的代码只保留加载它的逻辑这一步是物理拆分一个文件变成两个文件。2. 运行阶段主程序只加载 “入口代码”用户打开页面时浏览器只下载主包app.js被拆分的 async_Dialog.js 完全不请求、不下载页面体积更小、加载更快3. 触发时机动态创建btn.onclickasync(){// 执行这行时才真正开始加载const{default:Dialog}awaitimport(./Dialog.js)Dialog.open()}底层原生行为Webpack 注入的运行时代码会做一件事动态创建一个script srcasync_Dialog.js标签插入 head!--浏览器自动发送请求下载这个JS--script srcasync_Dialog.js/script这就是按需加载最本质的原理用原生 JS 动态发起脚本请求。4. 加载完成执行代码并返回模块浏览器下载完 async_Dialog.js立即执行里面的代码把导出的内容Dialog返回给 import() 的 Promise你就可以正常使用了3一句话总结核心逻辑按需引入 构建时拆包 运行时动态创建 script 标签懒加载 JS 文件构建工具Webpack/Vite负责切 chunk浏览器负责需要时再下载全程不需要服务端配合纯前端实现按需引入的本质需要时才通过script标签下载额外的JS文件谁来切分Webpack/Vite 看到 import() 就自动分 chunk谁来加载浏览器原生动态脚本加载能力好处首屏更快、流量更省③ 拆分配置splitChunks—— 最常用、最智能这是自动分块规则Webpack 根据 4 个维度拆分代码是否共享多个 chunk 共用的代码是否是第三方库node_modules 里的代码文件大小太小不分太大必须分加载时的请求数避免分太多导致请求过多默认规则开箱即用来自 node_modules 的库 → 拆成 vendors chunk被 ≥2 个 chunk 共享 的代码 → 拆成公共 chunk大小 ≥ 20kb 才会拆分太小不拆避免请求浪费✅ 依据公共代码 第三方库 体积 共享次数3分块到底是怎么 “分” 的执行流程用一句话总结流程Webpack 先收集所有依赖根据 entry /import () /splitChunks 规则 给依赖分组每组依赖 → 打包成 一个独立 chunk最终输出多个 JS 文件依赖集合[vue,axios,首页代码,详情页代码,公共工具]↓ 按规则分块chunk1(vendors)vueaxioschunk2(common)公共工具chunk3(home)首页代码chunk4(detail)详情页代码4 一句话终极总结分的对象chunk打包后的文件分的依据入口、动态导入、共享依赖、第三方库、体积分的目的拆包、懒加载、缓存优化、提升首屏速度总结分块 切 chunk不是切依赖分块依据entry 动态 import splitChunks 规则splitChunks 核心抽第三方库 抽公共代码 按大小 / 共享数拆分5. 前端 resolve路径解析模式 方法一、resolve 有 3 种解析模式固定这是所有前端构建工具统一的路径查找规则绝对路径模式例/src/utils.js、C:/project/src直接定位不搜索相对路径模式例./utils、…/components/Button相对于当前文件所在目录解析模块路径模式第三方包例react、axios、lodash去 node_modules 或配置的目录里找二、resolve 有 4 种核心配置方法固定这是 Webpack / Vite 最常用的 4 种解析配置alias 别名简化路径/utils → src/utilsextensions 自动补全后缀引入时不用写后缀import ‘./index’ 自动找 .js / .vue 等modules 模块查找目录告诉工具去哪里找第三方包默认 node_modulesmainFiles 入口主文件找目录时默认读取的文件如 index.js✅ 前端 resolve 路径解析3 种解析模式绝对路径、相对路径、模块路径4 种配置方法alias、extensions、modules、mainFiles6. 移动端适配的方式1、viewport 固定布局简单页面meta viewport 设置 widthdevice-width用 px 媒体查询 media适合简单活动页、官网2、rem 适配旧项目主流根据 html 根字体大小动态计算页面全部用 rem 单位代表flexible、手淘方案3、vw/vh 适配现代标准方案1vw 屏幕宽度的 1%直接写 vw不用 JS现在 最推荐4、flex % 媒体查询混合布局不用等比缩放结构用 flex宽度用 %适合大多数后台、小程序、App 内页面总结viewport px 媒体查询rem 动态适配vw/vh 适配现在主流flex 百分比混合布局6. 前端动画实现方式1、CSS3 transition简单过渡动画hover、显示隐藏等。2、CSS3 animation复杂关键帧动画配合 keyframes。3、JavaScript 动画setInterval / setTimeoutrequestAnimationFrame主流适合动态计算、交互强的动画4、Canvas / SVG 动画图表、粒子、复杂可视化、游戏类动画前端动画主要分CSS 动画和JS 动画两大类简单、性能优先用 CSS3 transition /animation复杂、交互控制用 JS requestAnimationFrame可视化、粒子用 Canvas / SVG7. JavaScript 如何判断可迭代对象JS 判断可迭代对象 检查 obj[Symbol.iterator] 是不是函数constisIterableobjobj!nulltypeofobj[Symbol.iterator]function;常见可迭代对象ArrayStringMapSetargumentsTypedArray不可迭代Object普通对象默认不可迭代number / null / undefined / booleanJavaScript 可迭代对象转数组的 4 种方法一、最推荐扩展运算符 …最简单、最常用// 用法[...可迭代对象]constarr1[...hello];// [h,e,l,l,o]constarr2[...newSet([1,2,3])];// [1,2,3]constarr3[...newMap([[1,a]])];// [[1,a]]constarr4[...document.querySelectorAll(div)];// 节点数组二、官方标准Array.from()功能最强大不仅能转可迭代对象还支持类数组有 length 的对象还能映射处理。constarr1Array.from(hello);// [h,e,l,l,o]constarr2Array.from(newSet([1,2]));// [1,2]// 进阶转换 直接处理数据constarr3Array.from([1,2,3],xx*2);// [2,4,6]三、老式兼容Array.prototype.slice.call()兼容 IE 等老环境现在不推荐但你可能会在旧代码里看到constarrArray.prototype.slice.call(arguments);四、循环遍历最原始手动遍历推入数组一般不用constsetnewSet([1,2,3]);constarr[];for(constitemofset)arr.push(item);
web前端知识点总结2026(二)
web前端知识点总结2026二1. foreach不能break的原理2. http1.1 一次tcp连接最多支持多少http请求3. 针对单个文件上传如何知道上传进度4. Webpack 分块Code Splitting核心原理5. 前端 resolve路径解析模式 方法6. 移动端适配的方式6. 前端动画实现方式7. JavaScript 如何判断可迭代对象1. foreach不能break的原理forEach 不是循环语法它是数组的方法 回调函数机制语法层面就不支持 break。详细原理1、本质不同for/for…of 是JS 原生循环语句语法上天生支持 break、continueforEach 是数组对象的一个方法它内部封装了循环逻辑你写的代码是在回调函数里不是在循环体里。2、作用域不匹配break 只能跳出当前所在的循环语句但你的回调函数是一个独立函数不在循环语句的作用域内。你在 forEach 回调里写 breakJS 根本找不到它属于哪个循环直接报错。3、设计初衷forEach 被设计出来的目的就是遍历数组的每一项必须全部执行完不允许中途中断。它的设计理念就是 “完整遍历”没有提供中断能力。总结forEach 是方法 回调函数不是循环语句break 是循环专用关键字只能在 for/while 等循环里用回调函数和循环不在同一个作用域语法不支持所以无法 break2. http1.1 一次tcp连接最多支持多少http请求HTTP/1.1 单个 TCP 连接本身可以发无数个请求长连接。浏览器限制同一域名最多 6 个并发 TCP 连接。超过 6 个请求会排队不会同时发。3. 针对单个文件上传如何知道上传进度前端上传文件时浏览器的网络请求对象XMLHttpRequest/fetch会触发上传进度事件事件对象会返回两个关键值loaded已经上传的字节数total文件总字节数通过 (loaded / total) * 100 就能计算出上传进度百分比。!DOCTYPEhtmlhtmlheadtitle文件上传进度/titlestyle.progress-bar{width:300px;height:10px;background:#eee;margin:10px0;}.progress{height:100%;background:#409eff;width:0%;transition:width0.2s;}/style/headbodyinput typefileidfileInput/divclassprogress-bardivclassprogressidprogress/div/divp idprogressText0%/pscriptconstfileInputdocument.getElementById(fileInput);constprogressBardocument.getElementById(progress);constprogressTextdocument.getElementById(progressText);// 选择文件后自动上传fileInput.addEventListener(change,(e){constfilee.target.files[0];if(!file)return;// 1. 创建请求对象constxhrnewXMLHttpRequest();// 2. 配置上传接口xhr.open(POST,/upload);// 替换为你的后端上传接口// 核心监听上传进度事件xhr.upload.addEventListener(progress,(event){if(event.lengthComputable){// 判断文件大小是否可计算// 计算进度百分比constpercent(event.loaded/event.total)*100;// 更新进度条和文字progressBar.style.widthpercent%;progressText.textContentpercent.toFixed(2)%;}});// 上传完成xhr.onload(){if(xhr.status200){progressText.textContent上传完成;}};// 3. 构建表单数据上传文件constformDatanewFormData();formData.append(file,file);// file 为后端接收的参数名// 4. 发送请求xhr.send(formData);});/script/body/html4. Webpack 分块Code Splitting核心原理1 分块分的是什么分的是 chunk代码块不是依赖依赖 你的代码文件、第三方库如 vue/react/lodashchunk Webpack 打包后生成的独立 JS 文件就是最终输出的 app.js、vendors~app.js 这种分块的本质把一堆依赖打包成若干个独立 chunk 文件而不是全部塞进一个大文件里。2分块是根据什么来分的核心规则Webpack 分块只有 3 大依据所有分块逻辑都源于此① 入口起点entry—— 最基础的分块你配置几个 entry就自动生成几个初始 chunk。entry:{home:./src/home.js,// 生成 home chunkadmin:./src/admin.js// 生成 admin chunk}✅ 依据多页面 / 多入口分离② 动态导入import ()—— 按需加载import(./DetailPage).then(module{...})Webpack 自动把 DetailPage 切成独立 chunk。✅ 依据用户不需要一开始就加载的代码路由、弹窗、懒加载模块1按需引入到底是什么不是只引入部分代码而是 “需要时才加载整个文件 / 模块”常规引入页面一打开所有代码一次性下载、执行按需引入页面打开只加载核心代码点按钮 / 切路由时再去下载额外的 JS 文件2按需引入的完整底层逻辑4 步1. 构建阶段Webpack 自动拆包你写一行动态导入// 你的代码constDialogimport(./Dialog.js)Webpack 背后做的事识别到 import() → 把 Dialog.js 单独切成一个独立 chunk比如 async_Dialog.js给这个 chunk 生成一个唯一标识主包里不包含这个文件的代码只保留加载它的逻辑这一步是物理拆分一个文件变成两个文件。2. 运行阶段主程序只加载 “入口代码”用户打开页面时浏览器只下载主包app.js被拆分的 async_Dialog.js 完全不请求、不下载页面体积更小、加载更快3. 触发时机动态创建btn.onclickasync(){// 执行这行时才真正开始加载const{default:Dialog}awaitimport(./Dialog.js)Dialog.open()}底层原生行为Webpack 注入的运行时代码会做一件事动态创建一个script srcasync_Dialog.js标签插入 head!--浏览器自动发送请求下载这个JS--script srcasync_Dialog.js/script这就是按需加载最本质的原理用原生 JS 动态发起脚本请求。4. 加载完成执行代码并返回模块浏览器下载完 async_Dialog.js立即执行里面的代码把导出的内容Dialog返回给 import() 的 Promise你就可以正常使用了3一句话总结核心逻辑按需引入 构建时拆包 运行时动态创建 script 标签懒加载 JS 文件构建工具Webpack/Vite负责切 chunk浏览器负责需要时再下载全程不需要服务端配合纯前端实现按需引入的本质需要时才通过script标签下载额外的JS文件谁来切分Webpack/Vite 看到 import() 就自动分 chunk谁来加载浏览器原生动态脚本加载能力好处首屏更快、流量更省③ 拆分配置splitChunks—— 最常用、最智能这是自动分块规则Webpack 根据 4 个维度拆分代码是否共享多个 chunk 共用的代码是否是第三方库node_modules 里的代码文件大小太小不分太大必须分加载时的请求数避免分太多导致请求过多默认规则开箱即用来自 node_modules 的库 → 拆成 vendors chunk被 ≥2 个 chunk 共享 的代码 → 拆成公共 chunk大小 ≥ 20kb 才会拆分太小不拆避免请求浪费✅ 依据公共代码 第三方库 体积 共享次数3分块到底是怎么 “分” 的执行流程用一句话总结流程Webpack 先收集所有依赖根据 entry /import () /splitChunks 规则 给依赖分组每组依赖 → 打包成 一个独立 chunk最终输出多个 JS 文件依赖集合[vue,axios,首页代码,详情页代码,公共工具]↓ 按规则分块chunk1(vendors)vueaxioschunk2(common)公共工具chunk3(home)首页代码chunk4(detail)详情页代码4 一句话终极总结分的对象chunk打包后的文件分的依据入口、动态导入、共享依赖、第三方库、体积分的目的拆包、懒加载、缓存优化、提升首屏速度总结分块 切 chunk不是切依赖分块依据entry 动态 import splitChunks 规则splitChunks 核心抽第三方库 抽公共代码 按大小 / 共享数拆分5. 前端 resolve路径解析模式 方法一、resolve 有 3 种解析模式固定这是所有前端构建工具统一的路径查找规则绝对路径模式例/src/utils.js、C:/project/src直接定位不搜索相对路径模式例./utils、…/components/Button相对于当前文件所在目录解析模块路径模式第三方包例react、axios、lodash去 node_modules 或配置的目录里找二、resolve 有 4 种核心配置方法固定这是 Webpack / Vite 最常用的 4 种解析配置alias 别名简化路径/utils → src/utilsextensions 自动补全后缀引入时不用写后缀import ‘./index’ 自动找 .js / .vue 等modules 模块查找目录告诉工具去哪里找第三方包默认 node_modulesmainFiles 入口主文件找目录时默认读取的文件如 index.js✅ 前端 resolve 路径解析3 种解析模式绝对路径、相对路径、模块路径4 种配置方法alias、extensions、modules、mainFiles6. 移动端适配的方式1、viewport 固定布局简单页面meta viewport 设置 widthdevice-width用 px 媒体查询 media适合简单活动页、官网2、rem 适配旧项目主流根据 html 根字体大小动态计算页面全部用 rem 单位代表flexible、手淘方案3、vw/vh 适配现代标准方案1vw 屏幕宽度的 1%直接写 vw不用 JS现在 最推荐4、flex % 媒体查询混合布局不用等比缩放结构用 flex宽度用 %适合大多数后台、小程序、App 内页面总结viewport px 媒体查询rem 动态适配vw/vh 适配现在主流flex 百分比混合布局6. 前端动画实现方式1、CSS3 transition简单过渡动画hover、显示隐藏等。2、CSS3 animation复杂关键帧动画配合 keyframes。3、JavaScript 动画setInterval / setTimeoutrequestAnimationFrame主流适合动态计算、交互强的动画4、Canvas / SVG 动画图表、粒子、复杂可视化、游戏类动画前端动画主要分CSS 动画和JS 动画两大类简单、性能优先用 CSS3 transition /animation复杂、交互控制用 JS requestAnimationFrame可视化、粒子用 Canvas / SVG7. JavaScript 如何判断可迭代对象JS 判断可迭代对象 检查 obj[Symbol.iterator] 是不是函数constisIterableobjobj!nulltypeofobj[Symbol.iterator]function;常见可迭代对象ArrayStringMapSetargumentsTypedArray不可迭代Object普通对象默认不可迭代number / null / undefined / booleanJavaScript 可迭代对象转数组的 4 种方法一、最推荐扩展运算符 …最简单、最常用// 用法[...可迭代对象]constarr1[...hello];// [h,e,l,l,o]constarr2[...newSet([1,2,3])];// [1,2,3]constarr3[...newMap([[1,a]])];// [[1,a]]constarr4[...document.querySelectorAll(div)];// 节点数组二、官方标准Array.from()功能最强大不仅能转可迭代对象还支持类数组有 length 的对象还能映射处理。constarr1Array.from(hello);// [h,e,l,l,o]constarr2Array.from(newSet([1,2]));// [1,2]// 进阶转换 直接处理数据constarr3Array.from([1,2,3],xx*2);// [2,4,6]三、老式兼容Array.prototype.slice.call()兼容 IE 等老环境现在不推荐但你可能会在旧代码里看到constarrArray.prototype.slice.call(arguments);四、循环遍历最原始手动遍历推入数组一般不用constsetnewSet([1,2,3]);constarr[];for(constitemofset)arr.push(item);