JavaScript基础核心概念详解:变量、类型、函数、闭包与异步
我教过不少刚接触代码的人发现大家学 JavaScript 都会经历同一个尴尬阶段跟着教程能写出例子合上教程就不知道下一步该干嘛。原因很简单——基础概念没有变成自己的。这篇文章是「JavaScript 基础」系列的第一讲目标只有一个把变量、类型、函数、作用域、对象、数组和异步这些最核心的地基概念讲透让你知道它们为什么存在、怎么用、以及哪些地方最容易踩坑。它适合完全零基础的朋友也适合学了一半回头补基础的人。你不需要安装任何复杂的工具打开浏览器按下 F12 就能跟着动手。1. 别急着敲代码先用地图理解 JavaScript 的真实面貌1.1 它到底能做什么比你以为的宽得多很多人第一次接触 JavaScript是从网页上的弹窗或者表单校验开始的。但它的能力边界远不止这些在浏览器里它可以操作页面上的元素、响应用户的点击和输入、向服务器请求数据、做动画、处理视频音频几乎所有现代网页交互的背后都有它的影子。出了浏览器Node.js 让 JavaScript 可以运行在服务器上写接口、处理文件、操作数据库都不在话下。再往外延伸小程序、桌面应用、甚至物联网设备上的脚本都有 JavaScript 的身影。换句话说只要你在和前端打交道或者对全栈、跨端开发感兴趣JavaScript 都是一道绕不开的门槛。框架再方便写到最后拼的还是基础。如果你以后要深入 Vue、React 这些框架面试时被反复追问的原生概念也正是这篇文章要讲的东西。1.2 JavaScript、Java 和 ECMAScript别把名字搞混了刚入门时很容易被几个名字绕晕。JavaScript 和 Java 是两门完全不同的语言只是因为诞生时的商业推广需要借了 Java 的名字语法上有相似之处但本质毫无关系。你不需要会 Java 才能学 JavaScript。ECMAScript 则是一门语言规范JavaScript 是对它的实现。平时大家说的 ES6、ES2015指的就是 ECMAScript 的版本。ES6 是 2015 年发布的版本引入了 let、const、箭头函数、类、模块化等一大批特性是现代前端开发的起点。你现在看到的大多数教程和框架代码默认都建立在 ES6 之上。所以当你看到ES6 语法这个词时可以把它理解为更现代、更推荐的 JavaScript 写法。1.3 环境准备一个浏览器加一个编辑器就够了学习基础阶段不需要搭复杂的工程化环境。我建议你这样起步打开 Chrome 或 Edge按 F12笔记本可能是 FnF12打开开发者工具切换到 Console控制台面板。在下面的输入框里直接输入console.log(hello world)回车你会立刻看到输出。想写多行代码时可以用任意一个顺手的文本编辑器新建一个index.html用script标签包裹 JavaScript 代码然后在浏览器里打开这个文件。!DOCTYPE html html langzh head meta charsetUTF-8 / title基础练习/title /head body script console.log(hello world); /script /body /html控制台是学习阶段最好的朋友。你可以把任何一段困惑的代码直接丢进去运行立刻看结果比反复查文档要快得多。这个习惯我从入门一直用到现在。2. 变量与数据类型新手最容易被类型转换坑到的地方2.1 var、let 和 const 三兄弟怎么选变量是数据的容器。ES6 之后声明变量有三种方式。很多人一开始搞不清差别其实从选择策略上非常简单默认用const需要重新赋值时用let至于var尽量不主动使用只在自己读老代码时能看懂就行。声明方式作用域可重复声明变量提升推荐度var函数作用域可以有但值是 undefined不推荐let块级作用域不可以语法上会报暂时性死区变量会变时用const块级作用域不可以同上默认首选const经常让人误会的地方是它不代表值不可变而是代表这个变量的绑定不可变。你可以修改对象内部的属性但不能重新给整个变量赋值。const person { name: 张三 }; person.name 李四; // 没问题改的是对象内部 person { name: 王五 }; // 报错Assignment to constant variablevar的坑则体现在作用域上。比如for (var i 0; i 3; i)里的i循环结束后依然存在可能污染外层变量。这在老代码里是经典的 bug 来源let就是为了解决这类问题诞生的。2.2 七种内置类型与 typeof 的返回值JavaScript 的数据类型主要分为原始类型和引用类型。原始类型包括 number、string、boolean、undefined、null、symbol、bigint引用类型主要是 object数组、函数、日期等都是对象的一种。判断类型最常用的工具是typeof操作符但它的返回结果有几个非常容易踩的坑。typeof 123; // number typeof abc; // string typeof true; // boolean typeof undefined; // undefined typeof null; // object ← 历史遗留bug typeof [1, 2, 3]; // object ← 数组也是对象 typeof function() {}; // function ← 特殊处理typeof null返回object是语言设计之初留下的历史 bug因为 null 的二进制表示全是零被类型判断误判成了对象。这个坑你记住就好。判断数组不能用typeof要用Array.isArray()判断一个对象是否为空可以拿Object.keys(obj).length看属性数量。2.3 强制转换和让人崩溃的隐式转换类型转换分为两种你用代码主动转换的叫显式转换运算时 JavaScript 自己偷偷帮你转的叫隐式转换。显式转换通常很安全Number(12); // 12 Number(12px); // NaN解析失败 String(123); // 123 Boolean(0); // false Boolean(0); // true非空字符串都算true隐式转换则是写基础代码时最容易栽跟头的地方。最经典的例子是加法运算1 1; // 11加号里遇到字符串就变成拼接 1 - 1; // 0减号会把字符串转成数字 5 * 2; // 10和的区别也在这里体现。0 false的结果是true因为会先做类型转换再比较0 false的结果是false因为要求类型和值都完全一致。我的建议非常简单粗暴永远使用和!把类型转换的隐性逻辑挡在门外。3. 函数与作用域理解 JavaScript 的执行逻辑3.1 声明函数与函数表达式看似一样实际上有差别函数是 JavaScript 的一等公民意思是它可以像普通值一样被赋值、被传递、被返回。写函数有几种常见方式// 函数声明 function add(a, b) { return a b; } // 函数表达式 const add2 function(a, b) { return a b; }; // 箭头函数 const add3 (a, b) a b;函数声明和函数表达式有一个关键差别提升。函数声明会被整体提升到作用域顶部所以你在声明之前调用它也不会报错函数表达式则像变量一样在赋值之前调用会得到undefined或者报错。箭头函数是 ES6 的语法糖写法简洁但它没有自己的arguments对象也没有自己的this这两个问题下面会说到。3.2 作用域与作用域链变量都去哪儿找作用域就是变量有效的范围。ES6 之后JavaScript 有全局作用域、函数作用域和块级作用域三种。var只有函数作用域而let和const是块级作用域一对大括号就是一个块。let x 1; function outer() { let x 2; function inner() { console.log(x); } inner(); } outer(); // 输出2当内层函数访问一个变量时会先从自己的作用域找找不到就往外一层找直到全局作用域这条链路就是作用域链。执行到inner时它自己的作用域里没有x于是往outer的作用域找到了x 2。理解这点之后很多为什么这里能访问那个变量的问题就迎刃而解了。3.3 闭包一个被概念吓住、其实很好懂的机制闭包的本质是一个函数能够记住并访问它定义时所在的作用域即使这个函数在定义的作用域之外被调用。口说无凭看个经典例子function createCounter() { let count 0; return function() { count; return count; }; } const counter createCounter(); console.log(counter()); // 1 console.log(counter()); // 2createCounter已经执行完了但返回的那个函数仍然可以通过作用域链访问到count变量于是这个变量被记住了。这就是闭包最常见的用途之一封装私有变量。外部没有办法直接修改count只能通过counter这个函数来操作它。闭包好用但要注意被闭包引用的变量会常驻内存不会被垃圾回收。所以如果一个闭包长期存在且没有释放可能造成内存占用。正常业务里不用过度紧张但大量循环里创建闭包时要留个心眼。3.4 this 指向调用方式说了算this是 JavaScript 里劝退新手最多的话题之一其实核心规则只有一条this的值取决于函数被谁调用。function showThis() { console.log(this); } showThis(); // 浏览器里是 window严格模式下是 undefined const obj { name: 对象, showThis: function() { console.log(this.name); } }; obj.showThis(); // 对象因为是 obj 调用的 setTimeout(function() { console.log(this); // window普通函数在定时器回调里丢失了调用者 }, 1000);箭头函数有点特殊它没有自己的this它会从定义它的外层作用域继承this。这个特性在异步回调里非常有用可以避免this丢失的问题。如果你在 React 或 Vue 里写过一个定时器内的this.setState却发现报错大概率就是普通函数和箭头函数this差异导致的。4. 数组与对象日常开发中使用频率最高的数据结构4.1 对象点号和方括号两种访问方式对象是键值对的集合几乎所有复杂的业务数据都可以用它表达。创建一个对象很简单const person { name: 张三, age: 30, full name: 张三丰, }; person.name; // 张三 person[name]; // 张三 person[full name]; // 张三丰属性名有空格必须用方括号点号写法更简洁但属性名是变量时必须要用方括号。比如const key name; person[key]才能取到值。删除属性用delete person.age遍历对象可以用Object.keys、Object.values、Object.entries三个方法它们分别返回属性名数组、属性值数组、键值对数组。新手最容易忽略的一点是对象是引用类型。赋值时复制的是引用不是内容。const a { x: 1 }; const b a; // b 和 a 指向同一个对象 b.x 2; console.log(a.x); // 2a 也被改了想真正复制一个对象可以用展开运算符const b { ...a }这只是浅拷贝嵌套对象仍然是共享的深拷贝要另想办法不过基础阶段先把浅拷贝的坑记住就好。4.2 数组的高频方法与原地操作的区别数组大概是日常开发里被用最多的数据结构。它的方法分成两类会修改原数组的和不会修改原数组的。会修改原数组的常用方法push尾部加、pop尾部删、shift头部删、unshift头部加、splice任意位置增删、sort排序、reverse反转。不会修改原数组、而是返回新数组的常用方法map逐一映射、filter筛选、slice切片、concat拼接。还有一个很实用的find返回第一个满足条件的元素。const nums [1, 2, 3, 4, 5]; const doubled nums.map(n n * 2); // [2, 4, 6, 8, 10] const even nums.filter(n n % 2 0); // [2, 4] const first nums.find(n n 3); // 4sort有一个反直觉的默认行为它按字符串而不是数字排序。[10, 9, 2, 1].sort()的结果是[1, 10, 2, 9]因为字符串比较是从第一位字符开始的。正确写法是arr.sort((a, b) a - b)。数组去重也简单[...new Set(arr)]一行就搞定。4.3 解构赋值与展开运算符让代码瘦身解构赋值是 ES6 里性价比极高的语法糖它让你从对象或数组中拆包变得非常方便。const person { name: 张三, age: 30, job: 工程师 }; const { name, age } person; // 从对象里取两个属性 console.log(name, age); // 张三 30 const arr [1, 2, 3, 4]; const [a, b, ...rest] arr; // a1, b2, rest[3,4] console.log(rest); // [3, 4] // 给解构设置默认值很常用 const { job 未知 } person; // job 有值就取没有就用默认值展开运算符...则可以把数组或对象的内容打散复制。const arr2 [...arr]复制数组const person2 { ...person, age: 31 }复制对象并覆盖某个属性。这种写法在 React 的不可变数据更新里尤其常见理解了展开运算符读框架代码会轻松很多。5. 异步编程入门从回调到 Promise理解 JS 的非阻塞特性5.1 为什么单线程的语言需要异步JavaScript 是单线程语言也就是说它一次只能做一件事。如果某件事耗时很长比如请求服务器数据、读取文件、等待定时器而你又必须等它完成才能继续页面就会卡住。这就是异步存在的意义把耗时的操作挂起先执行后面的代码等耗时操作完成了再回来处理结果。一个最直观的例子console.log(开始); setTimeout(() { console.log(1秒后执行); }, 1000); console.log(结束);输出顺序是开始、结束、1秒后执行。结束不会等定时器跑完再输出。很多人误以为setTimeout是延迟1秒执行更准确的理解是最短1秒后把回调放进执行队列。如果前面的代码执行时间超过1秒回调还得继续排队。5.2 回调函数与回调地狱异步的原始形态回调函数就是等某件事完成后再执行的函数。上面的setTimeout接受的箭头函数就是一个回调。异步操作最常见的写法就是传一个回调进去操作完成时调用。如果多个异步操作有先后依赖就会写成嵌套结构setTimeout(() { console.log(第一步完成); setTimeout(() { console.log(第二步完成); setTimeout(() { console.log(第三步完成); }, 1000); }, 1000); }, 1000);这就是回调地狱。它带来的问题不只是难看更重要的是错误处理分散、逻辑顺序混乱、后期维护困难。各大框架社区早就意识到这个问题于是 Promise 登场了。5.3 Promise 与 async/await把嵌套拉平Promise 是对异步结果的抽象它有三种状态pending进行中、fulfilled成功、rejected失败。状态只能从 pending 变为 fulfilled 或 rejected一旦变化就不能再改。function getData() { return new Promise((resolve, reject) { setTimeout(() { const success true; if (success) { resolve(请求到的数据); } else { reject(请求失败); } }, 1000); }); } getData() .then(data console.log(data)) .catch(error console.log(error));then接收成功结果catch接收失败原因。依赖关系通过链式的.then表达嵌套变成了平铺。在.then里返回一个 Promise还能继续往下串错误统一由最后的.catch捕获。async/await是 Promise 的语法糖让异步代码长得像同步代码async function run() { try { const data await getData(); console.log(data); } catch (error) { console.log(error); } } run();await会暂停当前函数等 Promise 出结果再继续。注意await只能在async函数里使用async函数始终返回一个 Promise。多个没有依赖关系的异步任务用Promise.all并发执行比逐个await快得多。const [user, posts] await Promise.all([ fetchUser(), fetchPosts() ]);异步是 JavaScript 进阶路上绕不过去的一道坎但把回调、Promise、async/await 这条线理顺之后后面看网络请求、API 封装都会顺畅很多。6. 新手必踩的坑与调试思路6.1 相等判断、分号和引号的细节基础阶段的报错和逻辑问题不少都集中在几个细节点上。第一个是相等判断前面说过一律使用不要用。第二个是分号JavaScript 会自动插入分号但自动插入并不总是符合你的预期比如以[或(开头的行很容易跟前一行产生奇怪的联动。我的建议是要么老老实实写分号要么坚持无分号风格保持一致最重要不要混用。第三个是字符串引号嵌套。单引号字符串里再用单引号会直接语法报错但双引号包单引号、单引号包双引号都没问题。ES6 新增的模板字符串用反引号包裹可以直接写变量和换行const name 张三; const message 你好${name} 今天学习JavaScript了吗;第四个是重复声明。同一个作用域里let或const声明同一个变量会直接报错这是新手经常碰到的 SyntaxError。同名的var则可以重复声明这是 var 的又一个历史包袱。6.2 调试不只是 console.logconsole.log是入门阶段的好朋友但它不是唯一工具甚至有时候会误导你。比如打印一个对象控制台里显示的是对象当前状态而不是打印那一刻的快照你展开它时看到的可能是修改后的值。几个更高效的玩法console.table([{ name: 张三, age: 30 }, { name: 李四, age: 25 }]); // 表格化展示数据多时一目了然 console.time(耗时); // 中间是某段操作 console.timeEnd(耗时); // 输出该段代码的执行耗时真正定位复杂 bug 时我建议用断点调试。在浏览器开发者工具的 Sources 面板里找到你的脚本文件点击行号打一个断点然后刷新页面。代码会执行到断点处暂停此时你可以在右侧查看所有作用域变量的当前值还能单步执行、跳进函数内部。这个体验比一个一个加console.log然后刷新猜原因要高效得多。6.3 读报错信息的正确姿势与排查顺序新手看到红色报错第一反应往往是慌其实报错信息是最高效的排错线索。一个典型的报错长这样Uncaught TypeError: person.name is not a function at anonymous:1:15第一行是错误类型和消息TypeError说明是类型相关的错误person.name is not a function说明你尝试当函数调用一个不是函数的值。第二行是出错位置1:15指文件第1行第15列点击可以跳转到具体代码。常见错误类型我列个快速对应表错误类型常见含义排查方向ReferenceError某个变量未定义检查拼写、是否漏写声明TypeError对不合适的类型做了操作检查对象是否 undefined、属性是否存在SyntaxError语法错误检查引号、括号、分号是否配对RangeError数值超出合法范围检查递归是否缺少出口、数组长度是否异常排查顺序也有讲究先看控制台里最顶部的第一条报错修复它然后再运行再看。很多时候后面一堆报错都是第一条引发的连锁反应第一条解决了后面的就消失了。如果报错信息看不懂把原文复制去搜索引擎旁边加上你使用的技术栈基本都能找到讨论帖。但切忌盲目复制答案要看懂别人解释的原理再动手修。我自己学基础时最有效的做法是把文章里的每一个例子亲手敲一遍然后故意改坏它看它会报什么错。报错不是失败是学习的一部分。这个系列后续会继续讲 DOM 操作和实战小案例如果你在照着敲代码的时候被某个报错卡住了先深吸一口气把报错信息读完再试着拆解它——读完这条报错你就已经比刚才又进一步了。

相关新闻

Modbus报文从入门到实战:帧结构、寄存器映射与CRC校验详解

Modbus报文从入门到实战:帧结构、寄存器映射与CRC校验详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 4:45:56 阅读更多 →
Personal Agent 省钱实战:从订阅替代到混合架构搭建

Personal Agent 省钱实战:从订阅替代到混合架构搭建

1. 从一条动态说起:Personal Agent 到底在解决什么问题前阵子刷到一条动态,标题大意是“又一 Personal Agent 发布,帮我省下不止200刀”。评论区一半人在问“这玩意儿到底能干啥”,另一半人在晒自己的订阅账单——原来大家每个月花…

2026/10/14 4:44:56 阅读更多 →
企业级通用Agent落地评估框架与工程化实战避坑指南

企业级通用Agent落地评估框架与工程化实战避坑指南

企业级通用 Agent 这两年被讨论得很多,但真正落到生产环境里跑通、跑稳、跑出业务价值的案例,远比发布会上的演示要少。我前后参与过几个不同行业的 Agent 项目,从最初的 POC 验证到后来的规模化部署,踩过的坑基本覆盖了评估报告里…

2026/10/14 4:44:56 阅读更多 →

最新新闻

电商AI视觉生产流水线:12个可编排图像生成Skill开源实践

电商AI视觉生产流水线:12个可编排图像生成Skill开源实践

1. 这不是又一个“AI画图工具”,而是电商视觉生产流水线的底层能力拆解你有没有遇到过这样的场景:运营同事凌晨两点发来消息,“明天大促主图要换,三套风格,带卖点文案,尺寸必须是800800和1200628双规格&…

2026/10/14 5:25:13 阅读更多 →
JavaScript正则方法全解析:从exec到replaceAll的实战指南

JavaScript正则方法全解析:从exec到replaceAll的实战指南

写正则的人最怕的不是正则写不出来,而是同一个需求,每个方法看起来都“差不多能用”,但真上线之后,Bug一个接一个。我见过好几次这样的情况:有人用match想拿捕获组,结果返回了一堆字符串;有人在…

2026/10/14 5:25:13 阅读更多 →
Apache Mesos 0.28.0 特性深度解析:net_cls 网络隔离、统一容器化与 v1 Executor HTTP API

Apache Mesos 0.28.0 特性深度解析:net_cls 网络隔离、统一容器化与 v1 Executor HTTP API

云原生 【免费下载链接】mesos Apache Mesos 项目地址: https://gitcode.com/gh_mirrors/mesos2/mesos 点击查看 免费下载 Apache Mesos 0.28.0 是 Mesos 发展历程中承上启下的一个重要版本:它在 Linux cgroups 网络隔离、标量资源精度、动态预留资源元…

2026/10/14 5:25:13 阅读更多 →
人体供暖系统:科学激活产热机制抵御寒冬

人体供暖系统:科学激活产热机制抵御寒冬

1. 寒冬里的主动发热之道最近几年冬天越来越难熬,特别是南方没有集中供暖的地区。作为一个在杭州生活了十年的北方人,我深刻体会到南方湿冷的威力——那种冷是往骨头缝里钻的。开空调太干燥,电热毯又只能局部取暖,于是我开始研究如…

2026/10/14 5:25:13 阅读更多 →
UE5 C++单播代理实战:DECLARE_DELEGATE与TDelegate全面解析

UE5 C++单播代理实战:DECLARE_DELEGATE与TDelegate全面解析

做游戏逻辑的时候,最常干的一件事就是把“某个行为”传递给“另一个系统”。按键按下的那一刻要通知谁,异步加载完关卡要提醒谁,血量掉到某个阈值要唤起谁——这些在UE5 C里最直接的落地方案就是代理(Delegate)。其中单…

2026/10/14 5:25:13 阅读更多 →
VC++ FTP服务器与客户端完整源码解析:从协议到断点续传实战

VC++ FTP服务器与客户端完整源码解析:从协议到断点续传实战

简介:一套面向VC/MFC与网络通信初学者的FTP客户端与服务器完整示例工程,基于VC6.0调试通过。工程同时提供控制台版本的FTP服务器和MFC界面客户端,源码头文件结构清晰,关键功能均以类接口形式开放,便于在此基础上扩展成…

2026/10/14 5:24:12 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →