跳到主要内容

为什么 '1'.toString() 可以调用?

面试速答(30 秒版 TL;DR)

  • '1' 是原始类型 string,按理说没有方法。
  • 但 JS 在你访问原始值的属性/方法时,会触发 装箱(boxing):临时把它包装成 String 对象,从 String.prototype 上找到方法并调用。
  • 调用结束后这个临时包装对象就会被丢弃。

心智模型:属性访问会触发 ToObject(装箱)

可以用这个“等价理解”(不是完全等价实现,但能解释现象):

// 你写的:
"1".toString();

// 可类比理解成:
new String("1").toString();

同理:

(1).toFixed(2);
true.toString();

但是注意:nullundefined 不能装箱,所以会直接抛错:

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:为什么 Stringprototype

  • 原始值在装箱后会“借用”对应构造函数的原型方法。
  • 所以 String.prototype 上的方法能被 "x" 这种原始字符串调用到。

Q2:装箱有性能问题吗?

大部分引擎会对装箱做优化;面试只要表达“这是语言机制,临时对象通常可被优化掉”即可,不要过度展开引擎细节。


易错点/坑

  • new String("a") 是对象,参与条件判断永远为真:
if (new Boolean(false)) {
// 会进来
}

这也是为什么不推荐显式包装对象。


速记要点(可背诵)

  • 原始值能调用方法靠装箱(ToObject),方法来自对应的 *.prototype
  • null/undefined 不能装箱,访问属性会直接抛错。