
在 JavaScript 中,同一表达式(如 str.lastIndexOf('_'))若在代码中多次出现,会被多次执行,而非缓存结果;因此为避免冗余计算,应将结果预先存储到变量中。
在 javascript 中,同一表达式(如 `str.lastindexof('_')`)若在代码中多次出现,会被多次执行,而非缓存结果;因此为避免冗余计算,应将结果预先存储到变量中。
当一个方法调用(尤其是涉及字符串搜索、正则匹配或复杂计算的函数)在条件判断和后续赋值中重复出现时,JavaScript 引擎不会自动记忆或复用前一次的返回值。例如:
let z = 99999;
if (str.lastIndexOf('_') !== -1) {
z = str.lastIndexOf('_'); // 再次调用!
}
这段代码中,str.lastIndexOf('_') 至少被调用两次:一次用于判断是否包含 '_',另一次用于获取实际索引位置。这不仅带来不必要的性能开销(尤其在长字符串或高频执行场景下),还可能引发副作用(如被重写的 lastIndexOf 中含 console.log 或状态变更逻辑)。
我们可以通过覆盖原型方法来验证这一点:
const orig = String.prototype.lastIndexOf;
String.prototype.lastIndexOf = function(...args) {
console.log('✅ lastIndexOf executed');
return orig.call(this, ...args); // 注意:必须 return 才能保持原行为
};
const str = 'hello_world';
let z = 99999;
if (str.lastIndexOf('_') !== -1) {
z = str.lastIndexOf('_');
}
// 控制台将输出两行 "✅ lastIndexOf executed"
同理,在三元运算符中重复书写也会触发多次执行:
// ❌ 不推荐:两次调用
z = str.lastIndexOf('_') !== -1 ? str.lastIndexOf('_') : 99999;
// ✅ 推荐:一次调用,复用结果
const idx = str.lastIndexOf('_');
z = idx !== -1 ? idx : 99999;
最佳实践总结:
- ✅ 总是将有副作用或高开销的方法调用结果缓存到局部变量中再复用;
- ✅ 即使当前字符串较短、性能影响微乎其微,也应养成“一次计算、多处使用”的编码习惯——这提升代码可读性、可维护性与确定性;
- ✅ 不依赖引擎优化“自动去重”,因为 JavaScript 规范未要求对纯函数做公共子表达式消除(CSE),且 V8 等引擎通常也不会为此类简单调用做跨语句优化。
简言之:不是“能否省略”,而是“为何要主动缓存”——这是健壮、可预测、符合直觉的工程选择。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











