JS对象与BOM协作指南:从类型判断到页面跳转高频实战
1. 从 JS 对象撞上 BOM 聊起一次重构翻车现场前段时间我重构一个老项目里的页面跳转逻辑原本只是想把散落在按钮回调里的 window.location.href xxx 抽成一个统一的导航配置对象。改完以后测试同学跑了一圈反馈说用户从订单详情页跳去登录登录成功后再返回居然回到了首页订单详情页被吞了。查了很久问题不在路由配置而是之前有人把订单详情页的参数对象用 JSON.stringify 塞进了 sessionStorage另一个页面在读取时用了 JSON.parse 却没做容错整个对象在 window.location 的跳转链路里被当字符串拼到了 query 上。一个对象和浏览器对象模型BOM的协作问题硬生生让整个导航链路断掉。这个 bug 看起来低级但它背后是一个非常典型的认知缺口很多人能把 JS 对象的 API 背得滚瓜烂熟也能说出 window、navigator、location 这些名词但一旦让对象真正和 BOM 协作起来马上露出破绽。用 sessionStorage 存对象要注意什么location.assign 和 location.replace 有什么区别iframe 里怎么刷新父页面恰恰是前端日常开发里最高频的痛点。先划个范围。BOM 这个缩写在制造业里指物料清单所以你会看到一堆人在搜Catia 二次开发 BOM 输出Cadence PCB 怎么导出 BOM 表KiCad 生成 BOM 文件这类词。但在前端语境下BOM 全称是 Browser Object Model翻译成中文叫浏览器对象模型。这篇文章只聊后者。如果你是被标题关键词吸引进来的硬件工程师对象这个章节对你仍然有用但 BOM 这一块请以浏览器为准。1.1 这篇文章解决什么问题我不打算把对象和 BOM 的 API 从头到尾抄一遍那样搜索引擎查文档就够了。我想做的是把这两块知识串起来先弄清 JS 对象的基本盘再理解浏览器暴露的 BOM 对象群最后落到真实场景比如判断对象为空、数组对象去重、iframe 父页面联动这类高频需求上。文中代码基本都可以复制后直接跑每段代码后面我会讲清楚为什么这么写而不是只丢一句抄这个。1.2 从热词里看见的高频痛点扫了一眼和这个主题相关的搜索热词除了js 对象和bom本身排在前面的有js 中函数是对象吗、判断对象为空、对象数组去重、es6 提取数组对象一部分、js 事件中的 event、iframe 关闭并刷新父页面 js。这些词拼在一起透露了一个规律大家不是缺教科书知识而是卡在了对象和浏览器机制的配合上。接下来的每一章我都会朝着这些痛点逐个击破。2. 先把对象的窗纸捅破JS 里万物皆对象但别迷信学习 JS 的人第一天就会听到一句话JS 里万物皆对象。这句话听起来热血真正用起来很容易踩坑。最经典的例子是 typeof null 返回 objecttypeof [] 也返回 object而 typeof function(){} 却返回 function。函数明明能挂属性、能走继承怎么 typeof 反而不是 object这就要把对象和函数的真实关系理清楚。2.1 typeof 的谎言null、数组、函数都算对象typeof 只能应付原始类型的判断面对对象类型时会给出三个返回值object、function、undefined。null 返回 object 是历史遗留 bug数组返回 object 是设计使然函数返回 function 则是语言特意区分的。所以想要精确判断一个值是数组、日期、正则还是普通对象我建议统一用 Object.prototype.toStringfunction getType(value) { return Object.prototype.toString.call(value); } getType([]); // [object Array] getType({}); // [object Object] getType(null); // [object Null] getType(new Date()); // [object Date] getType(/abc/); // [object RegExp]这个写法是业界最常见的类型判断方案核心原理是借用 Object.prototype.toString 方法让它内部的 this 指向被检测值从而拿到一个带对象的内部标签字符串。注意真正执行检测时必须写完整 Object.prototype.toString.call(value)直接调用 value.toString() 往往会被对象自身的 toString 方法覆盖结果就不对了。2.2 函数是对象吗是但它是可调用对象热词js 中函数是对象吗我单独讲一下。函数在 JS 里确实是对象它拥有普通对象的全部能力能挂属性、能被遍历自有键、也能通过 Object.keys 获取属性列表。但函数多了一个普通对象没有的能力可调用。在引擎内部函数实现了 [[Call]] 方法如果还能被 new就额外实现了 [[Construct]]这两者让函数可以出现在调用表达式里也能作为构造函数使用。function hello() {} hello.author geek; hello.say function () { console.log(hello); }; console.log(hello.author); // geek console.log(hello instanceof Object); // true hello.call(null); // 函数对象上的 call 方法来自 Function.prototype函数既然也是对象那它就能作为参数传递、作为返回值返回、被存进数组和对象这就是函数是一等公民的本质。看完这层闭包、高阶函数、回调函数这些概念会突然变得好理解。想要判断一个值到底是函数还是普通对象用 typeof 反而最准确因为 typeof 对函数有专属返回值 function正好能把两者区分开function isFunction(value) { return typeof value function; }2.3 创建对象的四种姿势以及原型链的底层逻辑创建对象有四种主流姿势对象字面量、构造函数、Object.create、ES6 class。它们的使用场景差别挺大我整理了一张表创建方式写法典型场景需要注意的点对象字面量const obj {}单例、配置对象、元数据最简单性能也好构造函数function User() {}; new User()需要复用和原型方法注意 new 的隐式返回逻辑Object.createObject.create(proto)自定义原型、纯净字典对象参数必须是对象或 nullES6 classclass User {}; new User()大型业务模型、领域对象本质是函数加原型链语法糖最容易被忽略的是构造函数的返回值。如果构造函数内部显式返回了一个对象那 new 出来的结果就不是 this 指向的新实例而是你返回的那个对象function User(name) { this.name name; return { hack: true }; } const user new User(张三); console.log(user.name); // undefined console.log(user.hack); // true这个行为很多初学者完全没想到导致封装构造函数的时候莫名其妙丢属性。还有 Object.create(null)它能创建出一个完全没有原型链的纯净对象不受 Object.prototype 上的任何污染方法影响非常适合做键值映射或者哈希容器。但注意它没有 toString、hasOwnProperty 这些常规方法想用必须借用 Object.prototype 上的方法写起来长一点换来的语义安全很值。原型链的规则其实一句话就能说清对象访问属性时先找自身找不到就沿着proto往父级找一直找到 Object.prototype再往上没有就直接返回 undefined。共享的方法放原型上每个实例独有的属性放 this 上这是最基本的实践。真正容易出问题的是给 Object.prototype 或 Array.prototype 挂自定义方法老代码里我见过一堆这种写法模块一多就开始互相干扰。能不上全局原型就不上宁可多写一层纯函数。2.4 this 指向对象里最反直觉的部分对象方法里的 this 遵循谁调用就指向谁的规则。这规则背起来容易套到回调、定时器、解构赋值里就开始玄学。最常见的坑是把方法单独拎出来调用const user { name: 张三, hello() { console.log(this.name); } }; const fn user.hello; fn(); // undefined因为调用者是全局对象根本没有 name 属性解决办法无非三种箭头函数固化 this、Function.prototype.bind 绑定、或者始终用点语法调用。很多搜索js 事件中的 event的人本质也是 this 和 event 两个概念在事件回调里打架。我建议凡是需要在回调里访问外部对象方法的场景直接写箭头函数最省心this 从词法上固定下来不管丢到哪个回调里都不会跑偏。3. 四个 BOM 核心对象搞懂它们代码才落地看完对象的基本盘回到 BOM。浏览器环境里的 JS 最早就是从 BOM 起步的只是很多教程把 DOM 讲得太重反把 BOM 冷落了。实际上没有 BOM页面根本无法跳转、无法存储数据、无法感知设备环境。这一章挑选四个最常用的 BOM 对象展开window、location、navigator、storage 相关对象。3.1 window所有对象的爹window 是 BOM 的根它既代表浏览器窗口本身又充当 JS 的全局作用域对象。最直观的证据是全局用 var 声明的变量会挂到 window 上let 和 const 不会var a 1; let b 2; console.log(window.a); // 1 console.log(window.b); // undefined这个差异在生产环境里影响很大。之前线上出过一个诡异问题有人在全局作用域用 var 声明了一个名为 status 的变量结果这个变量和 window.status 产生了冲突页面状态栏和行为一起异常。换成 let 之后立刻恢复。window 下面挂着一堆子对象navigator、location、history、screen 全部是它的属性理解了 window 这个爹其他 BOM API 就都是给儿子分门别类。3.2 location 与 history一个管你要去哪一个管你去过哪location 负责当前文档 URL 的解析与跳转项目里最常用的三个方法是 assign、replace、reload方法作用是否保留历史记录location.assign(url)跳转到新页面保留返回键能回来location.replace(url)用新页面替换当前页不保留按返回键不会回来location.reload()刷新当前页面不新增历史记录写登录跳转、表单提交跳转时replace 更常用因为用户不该通过返回键回到已提交的表单页。location.href 是属性直接给它赋值等价于调用 assign。还有一个容易被忽视的点修改 location.hash 不会刷新页面但会留下历史记录老项目里经常拿这个特性做简单的 tab 切换。history 对象在单页应用里尤其重要。pushState 和 replaceState 允许在不刷新页面的情况下修改地址栏 URL配合 popstate 事件就能实现完全可控的浏览器前进后退。开发里常遇到用户按了返回键要清理某些状态这类需求直接在 window 上监听 popstate 就好window.addEventListener(popstate, () { // 用户点击了浏览器返回键或者调用了 history.back() // 在这里做状态清理 });3.3 navigator 与 screen环境识别和显示适配navigator 是浏览器环境信息的集合日常用得最多的是这几个navigator.userAgentUA 字符串可辅助判断设备和浏览器但可以伪造不可当安全依据。navigator.language当前语言环境适合做国际化默认值。navigator.onLine网络是否在线常配合 online 和 offline 事件做断网提示。navigator.clipboard剪贴板读写要求 HTTPS 环境。有人会拿 navigator.userAgent 做反爬判断还有些工具会修改 UA 或者伪造 device 信息。需要提醒的是前端的环境识别永远是尽力而为不能当作安全边界真正的风控必须放服务端。screen 对象描述屏幕物理属性width 和 height 是屏幕总宽高availWidth 和 availHeight 是去掉系统任务栏后的可用尺寸。在做全屏展示或者大屏适配时比较 screen.width 和 window.innerWidth 的差异可以判断浏览器是否存在缩放比例或者是不是接入了外接屏这个小技巧很多前端工程师都在用。3.4 存储对象localStorage 与 sessionStorage 的正确姿势这两个兄弟是对象与 BOM 之间最常用的桥。共同点是都只能存字符串不同点是 localStorage 持久保存没有过期时间sessionStorage 在标签页关闭后自动清空。任何对象在存入之前都要序列化读出来之后再反序列化const order { id: 1024, items: [a, b] }; sessionStorage.setItem(order, JSON.stringify(order)); function readOrder() { const raw sessionStorage.getItem(order); return raw ? JSON.parse(raw) : null; }这段代码里其实藏着好几个安全边界。第一setItem 有抛异常的可能比如隐私模式下存储不可用或者存储已满。第二getItem 返回 null 时要有兜底值。第三JSON.parse 可能因为字符串被篡改或者格式损坏而抛异常生产代码建议再包一层 try/catch。另外 JSON.stringify 不会序列化函数属性Date 对象会变成字符串对象里值为 undefined 的属性会被静默丢弃。把这些坑记住比出去复制一个什么万能序列化工具都重要。4. 面向日常需求的对象操作清单对象相关的操作多到能写一本书但日常开发里真正高频的其实就那么几个。这里我按搜索热词的热度一个一个给出可直接复用的方案。4.1 判断对象为空别用 JSON.stringify判断对象为空是常驻热搜的需求。最常见的方案有三种// 方案 1Object.keys只统计自身可枚举属性 Object.keys(obj).length 0; // 方案 2Reflect.ownKeys连不可枚举属性和 Symbol 键一起统计 Reflect.ownKeys(obj).length 0; // 方案 3JSON.stringify最不推荐 JSON.stringify(obj) {};方案 3 看起来简单坑最多。对象里只要有值为 undefined 的属性或者函数属性JSON.stringify 会直接忽略一个明明有内容的对象序列化后变成 {}瞬间误判。方案 1 覆盖约九成业务场景方案 2 适合严谨场景比如对象可能带 Symbol 键。我习惯封装一个统一函数function isEmptyObject(value) { if (!value || typeof value ! object || Array.isArray(value)) { return false; } return Reflect.ownKeys(value).length 0; }这里做了类型前置校验数组、null 这些都不会被误判成空对象。4.2 数组对象去重Set 只对原始值有效原始值数组去重一行 Set 搞定[...new Set(arr)]。对象数组去重Set 直接失效因为两个对象哪怕内容完全一样引用也是不同的Set 会认为它们是两个不同元素。正确的思路是给对象提取一个唯一业务键再用 Map 收敛const list [ { id: 1, name: A }, { id: 2, name: B }, { id: 1, name: A } ]; const unique [...new Map(list.map(item [item.id, item])).values()]; console.log(unique); // [{ id: 1, name: A }, { id: 2, name: B }]这段代码最值得学的是它的数据流先把数组映射成 [key, value] 的二元数组交给 Map 根据 key 自动去重再取 values 转回数组。整个过程时间复杂度 O(n)几千条数据毫无压力。如果去重需要基于多个字段把字段拼接成一个字符串当 key 就行const key ${item.id}-${item.type};4.3 用 ES6 提取数组对象的一部分字段对接接口时后端返回的对象经常比前端需要的字段多得多。直接把整个对象丢给组件会造成脏字段泄漏、组件误判、依赖隐晦。用解构加 map 提取子集是干净又直观的写法const rawList [ { uid: 1, username: zhangsan, age: 18, extra: xxx }, { uid: 2, username: lisi, age: 20, extra: yyy } ]; const formatted rawList.map(({ uid, username }) ({ id: uid, name: username }));老式写法是循环里一个字段一个字段地 copy再想办法把不需要的字段删掉两相对比解构加 map 的方案不仅短而且意图完全外显。这种提取思维在 React 和 Vue 的 props 规范化里特别常用很多工程的代码规范里也会有后端字段不允许直接泄漏到视图层这类要求。4.4 忽略大小写判断、URL 有效性校验这类边角需求js 忽略大小写通常出现在搜索过滤、文件后缀判断等场景。最朴素的方案是统一转小写再判断包含function includesIgnoreCase(source, target) { return String(source).toLowerCase().includes(String(target).toLowerCase()); }不要一上来就上正则除非你真的需要通配符。正则的 i 标志确实能忽略大小写但写错转义反而更折腾可读性也差。URL 有效性校验我推荐优先用 new URL而不是手写正则function isValidUrl(url) { try { new URL(url); return true; } catch (e) { return false; } }new URL 的解析规则比手写正则完整得多协议、域名、端口、路径、IPv6 全都能正确处理遇到 abc 这种非法地址会主动抛异常。手写正则做 URL 校验特别容易漏掉合法地址比如只判断了 http/https 开头却漏了带端口、带中文编码参数的场景。前端浏览器环境用这个方案足够稳。4.5 对象转查询条件数据映射思维的迁移热词里出现对象转 querywrapper这是 Java 世界里 MyBatis-Plus 的查询条件构造器核心思路是把对象属性映射成数据库查询条件。这个思维在前端同样通用把筛选表单对象转成 URL query 参数是每个列表页都躲不开的活。我推荐封装一个通用函数function toQueryString(params) { return Object.entries(params) .filter(([, value]) value ! undefined value ! null value ! ) .map(([key, value]) ${encodeURIComponent(key)}${encodeURIComponent(value)}) .join(); } const result toQueryString({ page: 1, keyword: 前端, status: }); console.log(result); // page1keyword%E5%89%8D%E7%AB%AF这个函数和 QueryWrapper 的内核完全一致从目标数据结构出发决定对象该如何映射。空字符串、null、undefined 直接过滤避免 URL 上出现一堆无意义的空参数encodeURIComponent 负责处理中文和特殊字符防止乱码。对象在这里只是一个中间状态最终是要喂给 location 或者 fetch 的这就是对象和 BOM 最典型的协作场景。5. 结合 BOM 的实战事件、iframe、父页面联动前面讲的是对象和 BOM 各自的基本盘这一章专门落到真实场景把两者真正拧在一起。这里挑选的事件对象、iframe 父子页面协作、事件委托全是业务代码里高频出现的硬骨头。5.1 event 对象的常见陷阱js 事件中的 event是常年霸榜的搜索词。事件对象由浏览器在事件触发时自动创建并作为第一个参数传给监听函数。最常见的困惑是 target 和 currentTarget 的区别target 是事件真正发生的元素currentTarget 是绑定监听器的元素事件冒泡时两者经常不一致。parent.addEventListener(click, (event) { console.log(event.target); // 我实际点到的那个子元素 console.log(event.currentTarget); // parent 本身 });因为事件是从子元素一路冒泡到父级的挂在父级上的监听器event.target 往往是某个更深的子节点。遇到按钮里面嵌套 span、icon 的情况直接拿 target 判断点的是不是按钮很容易失效。更稳妥的做法是拿 target 向上找最近匹配的祖先const btn event.target.closest(button); if (!btn) return;closest 会从当前元素自身开始一路向上查找匹配选择器的祖先找不到就返回 null所以要做空值判断。这套组合拳能解决九成的动态列表点击问题。5.2 iframe 与父页面刷新窗口对象协作的一线案例热词iframe 关闭并刷新父页面 js的背后是一个非常经典的前端业务场景父页面打开一个 iframe 弹窗用户在弹窗里完成操作后关闭弹窗并刷新父页面列表。原理上就是访问窗口对象层级的关系// 在 iframe 内部操作父页面 window.parent.location.reload(); // 如果父页面暴露了全局方法也可以直接调用 window.parent.afterDialogClose window.parent.afterDialogClose(); // 父页面获取 iframe 内部的 window const iframeWindow document.getElementById(myIframe).contentWindow; iframeWindow.doSomething();这里最大的边界条件是同源策略只要两个窗口的协议、域名、端口任何一个不一致直接访问 window.parent 或者 iframe.contentWindow 就会被浏览器拦截抛跨域错误。安全的做法是用 postMessage 通信// 父页面监听消息 window.addEventListener(message, (event) { if (event.data.type dialog-done) { closeDialog(); location.reload(); } }); // iframe 内部发送消息 window.parent.postMessage({ type: dialog-done }, *);postMessage 的第二个参数建议限定可信域名不要把 * 当默认值一直用下去。这个经验在第三方支付、客服系统嵌套、后台管理系统的弹窗场景里会反复用到。5.3 事件委托用对象思维管理 DOM 事件动态列表如果每个按钮都单独 addEventListener页面元素一多监听器数量成倍膨胀内存和时间开销都会变大。事件委托把监听器统一挂到父级让事件冒泡到父级后再统一分发同时天然覆盖了动态新增元素没有监听器的痛点const container document.querySelector(.list); container.addEventListener(click, (event) { const btn event.target.closest([data-action]); if (!btn) return; switch (btn.dataset.action) { case edit: handleEdit(btn.dataset.id); break; case delete: handleDelete(btn.dataset.id); break; } });closest 会从当前元素向上找匹配选择器的祖先找不到返回 null所以加空的守卫是必须的。事件委托省监听器、兼容动态节点唯一注意的就是不要直接用 target 去取数据优先从 dataset 读取把事件对象和 DOM 元素对象当作普通数据处理代码的可维护性会明显上一个台阶。6. 写在后头对象思维决定前端天花板做了这么多年前端我的体会一直没变对象不是语法点而是一种建模语言。任何一个页面都可以拆成有哪些对象、对象之间怎么流转、对象在哪些 BOM 接口里进进出出。路由跳转本质上是 location 对象在读写 URL表单数据本质上是普通对象在 input 事件里被收集和校验页面状态本质上是对象在 localStorage、sessionStorage、全局变量、事件回调之间传递。我也踩过不少坑最大的教训是永远不要在业务代码里直接散落 JSON.stringify 和 localStorage 的裸调用。把它们封装成有语义的读写函数比如 saveOrder 和 loadOrder既方便以后切换存储方案也能让 bug 的定位范围一下子缩小很多。之前一次线上问题就是业务代码里直接调了 localStorage.getItem 又没有判空最后在函数入口补了一个防御就解决了。说到底真正难的不是记住 BOM 有哪些对象而是让一切对象在你脑子里形成一条清晰的流转路径它从哪里来要到哪里去中途经过哪些 BOM 接口。顺着这条路径写代码bug 会少一半这比背一百个 API 都值。

相关新闻

YOLO皮肤镜图像检测实战:2343张标注数据集训练与调优

YOLO皮肤镜图像检测实战:2343张标注数据集训练与调优

简介:本资源为面向皮肤疾病检测的YOLO系列目标检测数据集,适用于计算机视觉学习者、医学图像研究者及需要训练皮肤病灶识别模型的开发者。数据集覆盖怀特黑德、皱纹、皮肤发红、黑头、毛孔、痤疮等常见皮肤问题类别,可直接用于模型训练与验证…

2026/10/9 6:24:16 阅读更多 →
AI古诗短视频制作全流程:从文生图到电影感剪辑

AI古诗短视频制作全流程:从文生图到电影感剪辑

我先把话说在前面:网上那些"AI生成古诗视频,第一条就破万赞"的标题,水分很大,任何一个做内容的人都没法保证你抄了就能破万。但有一点是真的——古诗短视频是AI视频领域里最适合普通人上手的方向,素材成本极…

2026/10/9 6:24:16 阅读更多 →
滑动窗口解最小覆盖子串:双指针与哈希表实现 O(n) 匹配

滑动窗口解最小覆盖子串:双指针与哈希表实现 O(n) 匹配

“滑动窗口”这四个字,在算法面试里的出场率高到离谱;而“最小覆盖子串”又是滑动窗口家族里最能检验功力的那一道。字符串覆盖怎么判断、窗口什么时候该收缩、计数器状态怎么同步,哪一环掉链子,代码表面上跑得通,换一…

2026/10/9 6:24:16 阅读更多 →

最新新闻

可靠性测试别只会跑温箱振动台:失效物理与加速寿命是关键

可靠性测试别只会跑温箱振动台:失效物理与加速寿命是关键

干我们这行的,提起“可靠性测试”,不少人第一反应是:把样品扔进温箱里烤一烤、冻一冻,再放振动台上摇一摇,出来没坏就算通过。要是真这么想,那可靠性测试就白做了。作为一个和温箱、振动台、耐久跑法打了十…

2026/10/9 7:02:48 阅读更多 →
JVM内存模型与调优实战:从Minecraft OOM到HMCL配置

JVM内存模型与调优实战:从Minecraft OOM到HMCL配置

很多朋友第一次真正意识到 JVM 的存在,不是在 Java 课堂上,而是在一个完全不相关的场景里——玩游戏的时候。我用 HMCL 启动器给 Minecraft 装了个整合包,点了启动,等了两分钟,游戏闪退。把日志拉到最底部,…

2026/10/9 7:02:48 阅读更多 →
VS Code AI 语言模型配置全指南:模型切换、思维强度与 BYOK 自有密钥接入

VS Code AI 语言模型配置全指南:模型切换、思维强度与 BYOK 自有密钥接入

文档教程 【免费下载链接】vscode-docs Public documentation for Visual Studio Code 项目地址: https://gitcode.com/gh_mirrors/vs/vscode-docs 点击查看 免费下载 本文基于 Visual Studio Code 官方文档仓库(vscode-docs)中的 docs/agen…

2026/10/9 7:02:48 阅读更多 →
多标签文本分类实战复盘:从Embedding到Transformer的TAAC优化之路

多标签文本分类实战复盘:从Embedding到Transformer的TAAC优化之路

1. 从"vibe coding"说起:一个新手小白的TAAC复盘到底在复盘什么第一次看到"vibe coding"这个词,我脑子里蹦出来的画面是:一个人对着编辑器,凭感觉敲代码,跑通了就欢呼,跑不通就换一种写…

2026/10/9 7:02:48 阅读更多 →
内容团队如何用Qoder构建标准化AI工作流与协作机制

内容团队如何用Qoder构建标准化AI工作流与协作机制

团队里六个人,过去半年试过不下四个AI工具,从网页版问答到各种套壳应用,最后都回到同一个问题:AI确实能干活,但每个人干出来的活参差不齐,提示词散落在各自收藏夹里,换个项目就抓瞎。真正让我下…

2026/10/9 7:02:48 阅读更多 →
日期处理陷阱:从1月25日看时区与历法边界

日期处理陷阱:从1月25日看时区与历法边界

我很少拿一个日期当文章标题,但1月25日这个数字,我记了快一整年。不是因为它特殊——公历里它既不是节日也不算节气,每年对应的星期几、农历日子完全不一样。正因为它"每天都在变、又好像什么都没变",才在交付前一周把我…

2026/10/9 7:01:47 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 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/8 21:13:17 阅读更多 →
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/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练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/9 6:17:20 阅读更多 →