
文章目录 6
题目
下面代码的输出结果是什么?请解释原因。
function createCounter() {
let count = 0;
return function () {
count++;
return count;
};
}
const counterA = createCounter();
const counterB = createCounter();
console.log(counterA());
console.log(counterA());
console.log(counterB());
console.log(counterA());回答三个问题:
最终输出顺序是什么?
createCounter()执行结束后,为什么count没有被销毁?counterA和counterB为什么不会互相影响?
我的回答
1 2 1 3
因为闭包的特性,它可以访问外部作用域的变量,并持久化它的引用链
它们属于不同的对象,不同的作用域
解答
回答基本正确,评分:8.5/10。
正确点:
输出顺序完全正确:
1 2 1 3。正确认识到返回函数可以继续访问外层的
count。正确认识到两个计数器拥有独立状态。
需要更精确的地方:
- “持久化引用链”表达不够准确
更标准的说法是:
createCounter()返回的函数引用了其词法环境中的count。只要这个返回函数仍然可达,该词法环境就不能被垃圾回收。
并不意味着变量一定会永久存在。没有引用后,闭包和相关变量仍然可以被回收。
- 不是因为“属于不同对象”
核心原因是:createCounter() 每调用一次,都会创建一个新的和新的 count:
counterA → 闭包 A → count A
counterB → 闭包 B → count B两个返回函数分别引用不同的 count,所以互不影响。
面试标准表达:
最终输出
1、2、1、3。每次调用createCounter都会创建独立的词法环境,返回的函数形成闭包并引用其中的count。只要返回函数仍然存在,count就不会被垃圾回收。counterA和counterB来自两次不同调用,因此分别保存独立的count。
追问:
let counterA = createCounter();
counterA();
counterA = null;执行 counterA = null 后,原来的 count 是否可以被垃圾回收?为什么?
追问解答
counterA = null 后,如果没有其他引用指向原来的闭包,count 就可以被垃圾回收。
原因是:
let counterA = createCounter();
counterA(); // counterA 指向返回的函数
counterA = null; // 解除对返回函数的引用引用关系发生了变化:
赋值前:
counterA → 返回函数 → 词法环境 → count
赋值后:
counterA → null
原返回函数 → 不再可达
词法环境 → 不再可达
count → 可以被垃圾回收需要纠正两个关键点。
1. null 不是对象
null 是 JavaScript 的基本类型值。虽然:
typeof null === 'object';结果是 true,但这是 JavaScript 早期设计遗留的问题,不能据此认为 null 真的是对象。
判断 null 应该使用:
value === null2. “可以回收”不等于“立即回收”
执行:
counterA = null;只是让原来的函数和词法环境变成不可达状态。垃圾回收器什么时候真正释放内存,由 JavaScript 引擎决定。
标准回答:
counterA = null解除了变量对闭包函数的引用。如果没有其他地方继续引用该函数,那么函数及其捕获的词法环境都会变得不可达,count也就可以被垃圾回收。null是基本类型,typeof null === 'object'只是历史遗留问题。
相关文章
- 面试题-基础
Vue 3 响应式解构:为什么替换 user 后出现“李四 / 王五”
通过一道 Vue 3 代码题,区分 reactive 对象解构、嵌套属性修改与对象替换的行为,并用 toRef 保持源属性关联。文章保留首次作答及追问补答,说明从误判到纠正的过程。
- 面试题-基础
Vue 3 编辑弹窗:草稿状态、取消重开与父子数据契约
以一个始终挂载的姓名编辑弹窗为场景,给出覆盖数据归属、保存取消、重开初始化和外部更新冲突的完整 Vue 3 解法。结合首次回答与递进补答,说明本地草稿、脏标记和版本校验各自解决的问题。
- 面试题-基础
JavaScript 浅拷贝、深拷贝与 structuredClone:前端状态更新的正确方式
通过一道对象复制代码题,梳理 JavaScript 浅拷贝、JSON 深拷贝、structuredClone 和 transferable object 的边界,并解释 React 结构共享与 Vue 3 响应式更新的差异。
评论
0 条评论会在审核后展示,邮箱不会公开。