为什么 '1'.toString() 可以调用?
面试速答(30 秒版 TL;DR)
'1'是原始类型string,按理说没有方法。- 但 JS 在你访问原始值的属性/方法时,会触发 装箱(boxing):临时把它包装成
String对象,从String.prototype上找到方法并调用。 - 调用结束后这个临时包装对象就会被丢弃。
心智模型:属性访问会触发 ToObject(装箱)
可以用这个“等价理解”(不是完全等价实现,但能解释现象):
// 你写的:
"1".toString();
// 可类比理解成:
new String("1").toString();
同理:
(1).toFixed(2);
true.toString();
但是注意:null 和 undefined 不能装箱,所以会直接抛错:
null.toString(); // TypeError
undefined.toString(); // TypeError
为什么不建议显式使用包装对象?
const a = "1";
const b = new String("1");
typeof a; // "string"
typeof b; // "object"
a === "1"; // true
b === "1"; // false
结论:工程上几乎永远不需要 new String/Number/Boolean,用原始值即可。
典型题 & 标准答法
Q1:为什么 String 有 prototype?
- 原始值在装箱后会“借用”对应构造函数的原型方法。
- 所以
String.prototype上的方法能被"x"这种原始字符串调用到。
Q2:装箱有性能问题吗?
大部分引擎会对装箱做优化;面试只要表达“这是语言机制,临时对象通常可被优化掉”即可,不要过度展开引擎细节。
易错点/坑
new String("a")是对象,参与条件判断永远为真:
if (new Boolean(false)) {
// 会进来
}
这也是为什么不推荐显式包装对象。
速记要点(可背诵)
- 原始值能调用方法靠装箱(ToObject),方法来自对应的
*.prototype。 null/undefined不能装箱,访问属性会直接抛错。