金山面试题复盘

豆包

4 条消息 · 2026/10/10 16:39:54

我

在 JavaScript 中什么情况会进行装箱拆箱?

装箱拆箱是啥东西

AI 助手

JS 装箱(包装)/拆箱 讲解

JS里**原始值(string/number/boolean/symbol/bigint)**本身不是对象,没有属性和方法;装箱就是临时把原始值包装成对应的包装对象;拆箱就是把包装对象转回原始值。 包装对象:String、Number、Boolean、Symbol、BigInt

✅ 什么时候触发【装箱】

当你对原始值,访问属性/调用方法的时候,自动装箱

let a = 'hello'
console.log(a.length) 
// a是原始字符串,本身没有length属性
// JS临时 new String("hello") 生成包装对象 → 装箱
// 读取length,之后这个临时对象直接销毁

例子:

let num = 123
num.toString() // 原始数字调用方法,自动装箱成Number对象

✅ 什么时候触发【拆箱】

包装对象需要当作原始值使用时,自动拆箱

  1. 运算操作(加减、比较)
let obj = new Number(10)
console.log(obj + 5) // obj是包装对象,运算前拆箱得到10 → 15
  1. 使用==宽松相等比较
  2. 调用ToPrimitive(底层抽象操作),对象转原始值就是拆箱

考试简答答案(直接复制到答题框)

装箱:对原始类型值访问属性、调用方法时,JavaScript会自动创建对应的包装对象(String/Number/Boolean等),这个过程叫装箱。 拆箱:当包装对象参与运算、比较等操作,需要转为原始值时,会调用ToPrimitive将对象转换成原始数据类型,该过程为拆箱。

一句话精简版(适合这道5分简答题)

在对原始类型(字符串、数字、布尔等)进行面向对象操作(访问属性、调用方法)时触发装箱;包装对象参与运算、比较等需要原始值的场景,会触发拆箱转换。


补充小坑

let s = "abc"
s.test = 10 
// 装箱:临时new String("abc"),给临时对象加test属性,然后临时对象立刻销毁
console.log(s.test) // undefined
// 因为每次装箱都是新建临时对象,赋值的那个对象已经没了

要不要我再帮你区分一下 == 比较时拆箱的例子?

我
new Promise((resolve) => {
    console.log(1);
    resolve();
    console.log(2);
}).then(() => {
    console.log(3);
})
setTimeout(() => {
    console.log(4);
})
console.log(5);

这道题的输出是什么,为什么

AI 助手

输出顺序:1 → 2 → 5 → 3 → 4

1
2
5
3
4

完整执行拆解(JS事件循环,宏任务 / 微任务)

核心规则:先执行同步代码,同步全部跑完,再清空所有微任务队列,最后才执行宏任务 Promise 的 .then 属于微任务;setTimeout 属于宏任务

new Promise((resolve) => {
    console.log(1);   // ✅ 同步代码,立刻执行
    resolve();        // 修改Promise状态为成功,把.then回调放入【微任务队列】
    console.log(2);   // ✅ 同步代码,resolve不会终止函数!继续往下跑
}).then(() => {
    console.log(3);   // 🟢 微任务,等所有同步代码结束才执行
})

setTimeout(() => {
    console.log(4);   // 🔴 宏任务,放入宏任务队列,本轮全部微任务做完才轮到它
})

console.log(5);      // ✅ 同步代码,继续执行

分步走

  1. 进入 new Promise 执行器函数(executor),executor是同步执行
    • 打印 1
    • resolve():改变Promise状态,注册then回调到微任务队列
    • 打印 2(⚠️ 重点:resolve() 只是改状态,不会中断当前executor里面剩下代码)
  2. 退出Promise,执行setTimeout:把回调压入宏任务队列,不会立刻运行
  3. 执行最后的 console.log(5),打印5

✅ 同步代码全部执行完毕!现在去清空微任务队列

  1. 取出微任务:.then 的回调,打印3

✅ 微任务队列清空,本轮事件循环结束,开始执行宏任务

  1. 取出setTimeout宏任务回调,打印4

总结考点

  1. Promise 的 executor 构造器函数同步执行;
  2. resolve() 只是修改promise状态,不会终止当前函数代码;
  3. .then 回调属于微任务,setTimeout 是宏任务;
  4. 执行顺序优先级:同步代码 > 微任务 > 宏任务。

补充小测试:如果把resolve放最后

new Promise((resolve) => {
    console.log(1);
    console.log(2);
    resolve();
}).then(()=>console.log(3))

结果不变,1、2还是同步打印。

要不要我再给你一道同类事件循环题目练手?