JavaScript对象转基本类型时优先调用valueOf,若返回原始值则直接使用,否则调用toString;若二者均未返回原始值则报错。

JavaScript 中对象转基本类型时,会按规则自动调用 toString 和 valueOf 方法,但不是两者都用,而是有明确的优先级和上下文决定机制。
转换发生的典型场景
对象参与某些操作时会触发隐式类型转换,常见包括:
- 字符串拼接:
obj + '' - 使用
String(obj)显式转字符串 - 使用
Number(obj)或算术运算(如+obj、obj * 2) - 使用
Boolean(obj)(不过布尔转换不走这两个方法,总是 true)
toString 和 valueOf 的调用顺序
JS 引擎会按以下逻辑尝试获取原始值:
- 先尝试调用
valueOf(),如果返回的是原始类型(string/number/boolean/null/undefined/symbol),就直接使用这个结果 - 如果
valueOf()返回的仍是对象(包括this或新对象),则继续调用toString() - 如果
toString()返回原始类型,就用它;否则报错TypeError: Cannot convert object to primitive value
注意:这个流程在 ToPrimitive 抽象操作中定义,不同上下文(如 hint=“string” 或 hint=“number”)会影响初始偏好,但默认(hint=“default”)时,多数引擎(如 V8)会先试 valueOf,再试 toString。
立即学习“Java免费学习笔记(深入)”;
实际例子看执行过程
下面这个对象同时自定义了两个方法:
const obj = {
toString() {
console.log('toString called');
return 'from toString';
},
valueOf() {
console.log('valueOf called');
return 'from valueOf';
}
};
console.log(obj + ''); // 输出:'from valueOf'
结果是 'from valueOf',说明 valueOf 先被调,并且返回了字符串(原始值),所以没走到 toString。
再换一个例子,让 valueOf 返回对象:
const obj2 = {
toString() {
console.log('toString called');
return 'str';
},
valueOf() {
console.log('valueOf called');
return {}; // 返回对象 → 继续调 toString
}
};
console.log(String(obj2)); // 先 valueOf → 再 toString → 输出 'str'
如何控制转换行为
你可以通过重写这两个方法来定制对象在不同上下文中的表现:
- 想让对象在字符串环境中输出特定格式,重写
toString - 想让对象在数值计算中代表某个数字,重写
valueOf并返回 number - 若需区分 hint(比如
String(obj)偏好 string,Number(obj)偏好数值),可检查Symbol.toPrimitive(ES6+),它优先级高于toString/valueOf
例如,日期对象的 valueOf() 返回时间戳(number),所以 +new Date() 得到毫秒数;而 toString() 返回可读字符串,因此 '' + new Date() 是格式化文本。


















