
在 JavaScript 中,同一表达式(如 str.lastIndexOf('_'))若在代码中多次出现,会被重复执行而非缓存结果;实测证实其确实被调用两次,因此推荐将其结果预先存储到变量中以提升性能和可读性。
在 javascript 中,同一表达式(如 `str.lastindexof('_')`)若在代码中多次出现,会被重复执行而非缓存结果;实测证实其确实被调用两次,因此推荐将其结果预先存储到变量中以提升性能和可读性。
在实际开发中,看似简洁的内联写法可能隐藏性能陷阱。例如以下代码:
let z = 99999;
if (str.lastIndexOf('_') !== -1) {
z = str.lastIndexOf('_');
}
表面上逻辑清晰,但 str.lastIndexOf('_') 被执行了两次:一次用于条件判断,一次用于赋值。该方法需遍历字符串从末尾向前查找下划线位置,时间复杂度为 O(n),对长字符串或高频调用场景会造成不必要的开销。
我们可通过重写 String.prototype.lastIndexOf 进行验证:
const orig = String.prototype.lastIndexOf;
String.prototype.lastIndexOf = function(...args) {
console.log('running lastIndexOf');
return orig.call(this, ...args); // 注意:必须 return 才能保持原行为
};
const str = '31231231231312_1312312';
let z = 99999;
if (str.lastIndexOf('_') !== -1) {
z = str.lastIndexOf('_');
}
// 控制台将输出两次 "running lastIndexOf"
同理,三元运算符写法也存在相同问题:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
z = str.lastIndexOf('_') !== -1 ? str.lastIndexOf('_') : 99999; // ❌ 仍调用两次
✅ 正确做法是提取公共计算结果到中间变量:
const idx = str.lastIndexOf('_');
let z = idx !== -1 ? idx : 99999;
// 或更简洁地:
const z = str.lastIndexOf('_');
if (z === -1) z = 99999;
这种写法不仅避免重复计算,还提升了代码可读性与可维护性——变量名 idx 明确表达了语义(即“下划线最后出现的索引”),便于后续扩展(如添加边界检查、日志记录等)。
⚠️ 注意事项:
- 不要误以为 JavaScript 引擎会自动优化此类重复调用(目前主流引擎如 V8 并不进行跨语句的纯函数缓存推断);
- 对于副作用-free 的纯函数调用(如 Math.max()、Array.prototype.indexOf() 等),重复调用虽无功能错误,但牺牲性能与语义清晰度;
- 若方法有副作用(如修改内部状态、触发事件),重复调用可能导致逻辑错误,此时提取变量更是必需而非优化。
总结:“一次计算,多次使用” 是基础但关键的编码原则。将 lastIndexOf 等开销可观的操作结果显式缓存,既是性能最佳实践,也是专业代码可读性与健壮性的体现。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










