You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于toString与valueOf执行顺序的困惑及对象字符串转换异常问题

为什么对象字符串拼接时只调用了valueOf而非toString?

我们先拆解你遇到的场景:当执行"before "+f+" after"这种字符串拼接操作时,JS会对对象f执行ToPrimitive抽象操作——这个操作的核心是把对象转换为原始值,执行顺序取决于传入的hint参数(即转换的预期类型)。

对于加法操作来说,hint的值是"default"(因为加法既可能做数值运算也可能做字符串拼接,JS无法确定预期类型),此时ToPrimitive的执行规则是:

  • 优先调用对象的valueOf()方法,若返回的是原始值(数字、字符串、布尔值等非对象类型),则直接使用这个值,流程终止。
  • 只有当valueOf()返回的不是原始值时,才会继续调用toString()方法,再检查其返回值是否为原始值。

回到你的代码:

fn.prototype.valueOf = function(){
    console.log("valueOf call");
    return 100; // 返回的是原始值数字100
}

因为valueOf()直接返回了原始值100,ToPrimitive操作在这里就拿到了可用的原始值,根本不会再去调用toString(),所以你看不到toString call的输出,最终用100参与字符串拼接,得到before 100 after。

如果想让toString()先被触发,有两种方式:

  1. 让ToPrimitive的hint变为"string",比如使用模板字符串${f}:
    console.log(`before ${f} after`);
    
    此时ToPrimitive会优先调用toString(),但因为你的toString()返回的是对象{}(非原始值),所以会接着调用valueOf(),最终输出顺序就是你预期的toString call → valueOf call → before 100 after。
  2. 修改valueOf()让它返回非原始值,比如返回一个对象:
    fn.prototype.valueOf = function(){
        console.log("valueOf call");
        return {};
    }
    
    这时valueOf()返回非原始值,ToPrimitive会继续调用toString(),如果toString()返回原始值就用它,否则报错。

内容的提问来源于stack exchange,提问作者zhang xue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:52:35