7个JavaScript中关于闭包的面试题,你能回答上来吗?

7个JavaScript中关于闭包的面试题,你能回答上来吗?

相关推荐:2021年大前端面试题汇总(收藏)

每个 JavaScript 程序员都必须知道闭包是什么。在 JavaScript 面试中,你很可能会被问到闭包的概念。

以下是 7 个有关 JavaScript 闭包的面试题,比较有挑战性。

不要查看答案或运行代码,看看自己的水平到底如何。做完这些题大约需要半小时左右。

1. 范围

有以下函数 clickHandler,immediate和delayedReload:

立即学习“Java免费学习笔记(深入)”;

let countClicks = 0;button.addEventListener('click', function clickHandler() {  countClicks++;});const result = (function immediate(number) {  const message = `number is: ${number}`;  return message;})(100);setTimeout(function delayedReload() {  location.reload();}, 1000);

登录后复制

这3个函数中哪个能够访问外部范围变量?

答案

clickHandler 能够从外部作用域访问变量 countClicks。

immediate 无法访问外部作用域中的任何变量。

delayedReload 从全局作用域(也就是最外层作用域)中访问全局变量 location。

相关教程推荐:javascript视频教程

2.  丢失的参数

下列代码输出什么:

(function immediateA(a) {  return (function immediateB(b) {    console.log(a); // => ?  })(1);})(0);

登录后复制

答案

输出为:0

用参数 0 调用 immediateA,因此 a 参数为 0。

immediateB 函数嵌套在 immediateA 函数中,是一个闭包,它从外部 immediateA 作用域中得到 a 变量,其中 a 为 0。因此 console.log(a) 的输出为 0。

3. 谁是谁

下面的代码将会输出什么内容?

let count = 0;(function immediate() {  if (count === 0) {    let count = 1;    console.log(count); // 输出什么?  }  console.log(count); // 输出什么?})();

登录后复制

答案

输出 1 和 0

第一个语句  let count = 0 声明了一个变量 count。

immediate() 是一个闭包,它从外部作用域得到 count 变量。在 immediate()  函数作用域内, count 是 0。

但是,在条件内,另一个 let count = 1 声明了局部变量 count,该变量覆盖了作用域之外的 count。第一个 console.log(count) 输出 1。

第二个 console.log(count) 输出为 0 ,因为这里的 count 变量是从外部作用域访问的。

4. 棘手的闭包

下列代码输出什么:

for (var i = 0; i  ?  }, 1000);}

登录后复制

答案

输出:3, 3, 3。

代码分为两个阶段执行。

阶段1

for() 重复 3 次。在每次循环都会创建一个新函数 log(),该函数将捕获变量 i。 setTimout() 安排log() 在 1000 毫秒后执行。当 for() 循环完成时,变量 i 的值为 3。

阶段2

第二阶段发生在 1000ms 之后:

setTimeout() 执行预定的 log() 函数。 log() 读取变量 i 当前的值 3,并输出 3

所以输出 3, 3, 3。

5. 错误的信息

下面的代码将会输出什么:

function createIncrement() {  let count = 0;  function increment() {     count++;  }  let message = `Count is ${count}`;  function log() {    console.log(message);  }    return [increment, log];}const [increment, log] = createIncrement();increment(); increment(); increment(); log(); // => ?

登录后复制

答案

输出:’Count is 0′

increment() 函数被调用 3 次,将 count 增加到 3。

message 变量存在于 createIncrement() 函数的作用域内。其初始值为 ‘Count is 0’。但即使 count 变量已经增加了几次,message 变量的值也始终为 ‘Count is 0’。

log() 函数是一个闭包,它从 createIncrement() 作用域中获取 message 变量。 console.log(message) 输出录’Count is 0’到控制台。

6. 重新封装

下面的函数 createStack() 用于创建栈结构:

function createStack() {  return {    items: [],    push(item) {      this.items.push(item);    },    pop() {      return this.items.pop();    }  };}const stack = createStack();stack.push(10);stack.push(5);stack.pop(); // => 5stack.items; // => [10]stack.items = [10, 100, 1000]; // 栈结构的封装被破坏了

登录后复制

它能正常工作,但有一个小问题,因为暴露了 stack.items 属性,所以任何人都可以直接修改 items 数组。

这是一个大问题,因为它破坏了栈的封装:应该只有 push() 和 pop() 方法是公开的,而 stack.items 或其他任何细节都不能被访问。

使用闭包的概念重构上面的栈实现,这样就无法在 createStack() 函数作用域之外访问 items 数组:

function createStack() {  // 把你的代码写在这里}const stack = createStack();stack.push(10);stack.push(5);stack.pop(); // => 5stack.items; // => undefined

登录后复制

答案

以下是对 createStack() 的重构:

function createStack() {  const items = [];  return {    push(item) {      items.push(item);    },    pop() {      return items.pop();    }  };}const stack = createStack();stack.push(10);stack.push(5);stack.pop(); // => 5stack.items; // => undefined

登录后复制

items 已被移至 createStack() 作用域内。

这样修改后,从 createStack() 作用域的外部无法访问或修改 items 数组。现在 items 是一个私有变量,并且栈被封装:只有 push() 和 pop() 方法是公共的。

push() 和 pop() 方法是闭包,它们从 createStack() 函数作用域中得到 items 变量。

7. 智能乘法

编写一个函数  multiply() ,将两个数字相乘:

function multiply(num1, num2) {  // 把你的代码写在这里...}

登录后复制

要求:

如果用 2 个参数调用 multiply(num1,numb2),则应返回这 2 个参数的乘积。

但是如果用 1个参数调用,则该函数应返回另一个函数: const anotherFunc = multiply(num1) 。返回的函数在调用 anotherFunc(num2)  时执行乘法  num1 * num2。

multiply(4, 5); // => 20multiply(3, 3); // => 9const double = multiply(2);double(5);  // => 10double(11); // => 22

登录后复制

答案

以下是  multiply()  函数的一种实现方式:

function multiply(number1, number2) {  if (number2 !== undefined) {    return number1 * number2;  }  return function doMultiply(number2) {    return number1 * number2;  };}multiply(4, 5); // => 20multiply(3, 3); // => 9const double = multiply(2);double(5);  // => 10double(11); // => 22

登录后复制

如果 number2 参数不是 undefined,则该函数仅返回 number1 * number2。

但是,如果 number2 是 undefined,则意味着已经使用一个参数调用了 multiply() 函数。这时就要返回一个函数 doMultiply(),该函数稍后被调用时将执行实际的乘法运算。

doMultiply() 是闭包,因为它从 multiply() 作用域中得到了number1 变量。

总结

如果你答对了 5 个以上,说明对闭包掌握的很好。如果你答对了不到 5 个,则需要好好的复习一下了。

原文地址:https://dmitripavlutin.com/simple-explanation-of-javascript-closures/

转载地址:https://segmentfault.com/a/1190000039366748

更多编程相关知识,请访问:编程视频!!

以上就是7个JavaScript中关于闭包的面试题,你能回答上来吗?的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2716715.html

(0)
上一篇 2025年3月7日 21:58:06
下一篇 2025年2月18日 03:16:04

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 如何解决javascript乱码问题

    javascript乱码的解决办法:1、用编辑器打开,并选择和原文件编码一致的编码方式查看;2、选中乱码的“XX.js”,然后保存时更改编码;3、以UTF-8的编码方式保存等等。 本文操作环境:windows7系统、javascript1.…

    2025年3月7日
    200
  • javascript怎么让div隐藏

    javascript让div隐藏的方法:首先使用div标签创建一个模块,并设置其id为mydiv;然后使用button标签创建一个按钮,并给button按钮绑定onclick点击事件;最后在js标签中,创建hideDiv()函数即可。 本文…

    2025年3月7日 编程技术
    200
  • javascript怎么去掉字符

    javascript去掉字符的方法:首先使用input标签创建一个字符串输入框,并设置其id属性为myinput;然后创建button按钮并绑定onclick点击事件;接着在js内创建del函数;最后使用replace方法替换字符串即可。 …

    2025年3月7日 编程技术
    200
  • javascript如何去掉空格

    javascript去掉空格的方法:1、通过“str.replace(/s+/g,””);”去除所有空格;2、通过“str.replace(/^s+|s+$/g,””);”去除两头空格等等。 …

    2025年3月7日
    200
  • javascript怎么清除缓存

    javascript清除缓存的方法:1、通过meta方法清理网站缓存;2、用ajax请求服务器最新文件,并加上请求头“If-Modified-Since”和“Cache-Control”;3、直接使用“cache:false”等等。 本文操…

    2025年3月7日
    200
  • JavaScript如何删除HTML元素

    JavaScript删除HTML元素的方法:1、删除节点,代码为【removeChild(oldNode)】;2、删除列表框下拉菜单的选项,代码为【remove(long index)】。 本教程操作环境:windows7系统、javasc…

    2025年3月7日 编程技术
    200
  • 如何关闭javascript网页

    关闭javascript网页的方法:1、不带任何提示关闭窗口,代码为【 本教程操作环境:windows7系统、javascript1.8.5版,DELL G3电脑。 关闭javascript网页的方法: 1、不带任何提示关闭窗口的js代码 …

    2025年3月7日
    200
  • javascript怎么实现字符串转大写

    javascript实现字符串转大写的方法:1、通过“str.toUpperCase”方法将字符串转大写并返回;2、通过“str.toLocaleUpperCase”方法将字符串根据本地化的大小写映射规则转化成的大写形式的新字符串。 本文操…

    2025年3月7日
    200
  • javascript如何打印

    javascript打印输出的方法:1、通过“window.alert(‘弹出窗口调试’);”方式进行打印输出;2、通过“console.table(ars);”方式进行打印输出。 本文操作环境:windows7系统…

    2025年3月7日 编程技术
    200
  • javascript怎么去掉回车

    javascript去掉回车的方法:首先打开相应的js文件内容;然后通过“str.replaceAll(“(||()|(u0085)|(u2028)|(u2029))”, “”)”方式去除回车…

    2025年3月7日
    200

发表回复

登录后才能评论