JavaScript闭包:面试常考题及解析
1. 什么是JavaScript里的闭包?
答案:
在 JavaScript 中,当一个内部函数在外部函数内定义并能够访问外部函数的变量和参数时,这就形成了一个闭包。即使外部函数执行结束,内部函数仍可访问这些变量。
2. 为什么闭包在JavaScript里这么重要?
回答:
闭包在JavaScript里很重要,因为它们能封装数据并保持函数私有。它们有助于保持全局作用域的整洁,并能够创建从外部无法访问的私有变量。这也是面向对象编程的一个核心特性。
3. 你能给我一个 JavaScript 中闭包的例子吗?
答案:
function outerFunction() {
let outerVariable = "Hello, ";
function innerFunction(name) {
// 控制台输出
console.log(outerVariable + name);
}
return innerFunction;
}
var inner = outerFunction();
inner("John"); // 输出结果: "Hello, John"
点击进入全屏模式 点击退出全屏模式
在这个例子中,innerFunction 是一个闭包,因为它可以在 outerFunction 执行结束后仍然访问 outerFunction 中定义的 outerVariable。
4. 如何在 JavaScript 中使用闭包?
答案:
在 JavaScript 中,你可以通过在内层函数内定义一个外层函数并返回该内层函数来使用一个闭包。即使外层函数执行完成后,内层函数仍然可以访问外层函数的变量及参数。
5. 输出会是什么?
定义一个名为outer的函数 {
var x = 10;
定义一个名为inner的函数 {
在控制台打印x;
}
返回inner;
}
定义一个变量innerFunc并赋值为outer函数的返回值;
innerFunc();
全屏开启,取消全屏
答案:
输出:10
解释: 外层函数返回内层函数,内层函数可以访问在外层函数中声明的变量 x。调用内层函数时,它会打印 x 的值,x 的值还是 10。
6. 这段代码的输出会是什么:
function outer() {
var x = 10;
function inner() {
console.log(x);
}
x = 20;
return inner;
}
var innerFunc = outer();
innerFunc();
这段代码展示了一个闭包的使用。outer
函数返回一个内部函数 inner
,该函数在调用时会输出 x
的当前值。
切换到全屏模式,退出全屏模式
解析:
输出: 20.
解释: 在返回 inner 之前,x 的值更新为 20。当调用 innerFunc 时,它会输出更新后的 x 值,也就是 20。
7. 下面这段代码会输出什么呢
function 外层函数() {
var x = 10; // x 为 10
function 内层函数() {
var y = 5; // y 为 5
console.log(x + y); // 输出 x + y 的结果
}
return 内层函数;
}
var innerFunc = 外层函数();
innerFunc(); // 输出结果: 15
全屏 退出全屏
答案:
输出: 15
解释: inner 函数可以访问外部的 x (10) 和它自己的 y (5),所以输出是 15。
下面这段代码的输出会是什么?
function outer() {
var x = 10;
function inner() {
var y = 5;
console.log(x + y);
}
var x = 20;
return inner;
}
var innerFunc = outer();
innerFunc();
全屏:进入 退出
答案:
输出: 25
说明: 在外函数执行完毕之前,变量 x 被重新赋值为 20。当调用 innerFunc 时,它会输出 x 加 y 的结果,也就是 20 加 5 等于 25。
9 下面的代码:输出会是什么?
function outer() {
var x = 10;
function inner() {
var y = 5;
console.log(x + y);
x = 20;
}
return inner;
}
var innerFunc = outer();
innerFunc();
innerFunc();
全屏 退出全屏
回答:
输出结果:
第一次调用结果: 15。
第二次调用结果: 25。
解释: 第一次调用时,x 是 10,y 是 5,所以结果为 15。更新 x 为 20 后,第二次调用结果为 20 加 5,也就是 25。
10. 在 JavaScript 中何时使用 closure(闭包)
回答:
当你需要保持私有状态或封装那些全局作用域中无法访问的变量时,就会使用闭包。它们在创建数据隐私方面特别有用,尤其是在你想限制某些变量的访问并控制它们的访问和修改范围时。
11. 闭包和回调有什么区别?
回答:
闭包是一个记住创建环境的函数。即使外部函数已结束,它仍然可以访问外部函数中的变量。而回调是一个作为参数传递给另一个函数的函数,并在外部函数完成后执行该回调。
12. 什么是两种闭包类型?
答案:
在 JavaScript 里,有两种类型的闭包:词法闭包和动态闭包。词法闭包在编译阶段创建,能够访问词法作用域中的变量,而动态闭包在运行时创建,能够访问动态作用域中的变量。
13. Lambda 表达式和闭包是一样的吗?
_回答: *
在 JavaScript 中,lambda 函数其实就是一种没有名字的匿名函数。而闭包则是一个保留对外部函数变量访问权限的函数,即使外部函数已经返回。虽然 lambda 函数可以形成闭包,但它们并不相同。
14. 柯里化和闭包有什么区别?
回答:
柯里化是将一个多参数函数转换为一系列单参数函数的过程。另一方面,闭包是一个能够访问其外部函数作用域内变量的函数。柯里化可以利用闭包,但它们代表了不同的概念。
15. 代码闭包和封装是不是一回事?
答案:
闭包和封装是相关的但并不完全相同。封装指的是将数据和操作这些数据的方法捆绑在一起,形成一个单一的单元,通常是一个类(例如:Class),并限制对某些组件的访问。闭包指的是一个函数可以访问其外部函数中的变量,虽然闭包可以用来封装数据,但它们并不等同于封装。
16. JavaScript 是否支持嵌套(或内部)函数?如果支持,它们是如何工作的?
答:
是的,JavaScript 支持在函数内部定义的函数。这些函数可以使用外部函数的变量和参数。这样就可以实现闭包、封装模块,并构建更清晰的代码结构。
function sayHiBye(firstName, lastName) {
// 一个帮助函数,用于下面
function getFullName() {
return firstName + ' ' + lastName;
}
console.log('嗨,' + getFullName());
console.log('再见,' + getFullName());
}
全屏,退出全屏
17. 你能解释一下JavaScript中的词法环境是怎么回事吗?
回答:
在 JavaScript 中,词法作用域是一种结构,用于保存特定作用域中的变量、函数及其他值。它是 JavaScript 执行上下文中不可或缺的一部分,有助于在运行时如何访问和解析这些变量。
18. 垃圾回收在JavaScript中是如何处理作用域和嵌套函数的?
答案:
在 JavaScript 中,垃圾回收是指释放不再需要的对象所占用的内存。当创建一个函数并形成闭包后,存储变量引用的词法作用域可能阻止内存回收,直到不再使用该闭包。
function f() {
let value = 123;
return function () {
console.log(value);
};
}
let g = f(); // g.[[Environment]] 保存了对环境的引用
// g 存在时,值会保留在内存中
g = null; // 现在内存就可以被清理了
进入全屏,退出全屏
19. JavaScript 中的闭包有哪些常见用法?
答案:
闭包的常见用例包括数据封装、函数生成器、缓存函数、实现装饰器以及在异步编程中维护状态。
20. 在 JavaScript 中使用闭包有什么好处?
答案:
JavaScript中的闭包提供了多种优势,比如私有属性、创建函数的工厂以及在函数调用间保持状态。它们使代码更加强大、易于维护及模块化,并支持JavaScript中的函数式编程风格。
21. 在使用 JavaScript 的时候遇到 closures 有哪些需要注意的缺点或坑?
答案:
如果不对闭包进行妥善管理,闭包可能导致潜在风险,如内存泄漏,或者意外修改外部变量。
22. 闭包对JavaScript的垃圾回收机制有什么影响?
回答:
闭包会保持对外部函数中变量的引用,即使这些变量已经不再使用。这可能会阻止垃圾回收器释放不再需要的对象所占用的内存。
🔗 在我的领英上与我联系
让我们一起更深入地探索软件工程的世界吧!我经常分享关于JavaScript、TypeScript、Node.js、React、Next.js、数据结构与算法、网页开发等领域的见解和知识。无论你是想提升技能还是合作探讨有趣的话题,我都希望能和你一起交流和进步。
关注我:Nozibul Islam.
共同学习,写下你的评论
评论加载中...
作者其他优质文章