当前位置: 首页 > news >正文

闭包+面试真题

对闭包的理解

闭包是内层函数使用外层变量
(子级可以访问父级的变量,但是父级不可以访问子级的)

闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部变量。

闭包有两个常用的用途;

  • 闭包的第一个用途是使我们在函数外部能够访问到函数内部的变量。通过使用闭包,可以通过在外部调用闭包函数,从而在外部访问到函数内部的变量,可以使用这种方法来创建私有变量。
  • 闭包的另一个用途是使已经运行结束的函数上下文中的变量对象继续留在内存中,因为闭包函数保留了这个变量对象的引用,所以这个变量对象不会被回收。
    这是因为 JavaScript 的垃圾回收机制会检查对象是否还被引用,如果没有引用,则认为该对象是垃圾,可以被回收。而闭包的内部函数可能会继续访问外部函数的变量。只有当闭包函数本身也被销毁时,其引用的外部作用域才会被释放。
    比如,函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包。
function A() {let a = 1;window.B = function () {console.log(a);};
}
A();
B(); // 1

面试真题

1. 基础题

在 JS 中,闭包存在的意义就是让我们可以间接访问函数内部的变量。经典面试题:循环中使用闭包解决 var 定义函数的问题

for (var i = 1; i <= 5; i++) {setTimeout(function timer() {console.log(i);}, i * 1000);
}

首先因为 setTimeout 是个异步函数,所以会先把循环全部执行完毕,这时候 i 就是 6 了,所以会输出一堆 6。解决办法有三种:

  • 第一种是使用闭包的方式
for (var i = 1; i <= 5; i++) {(function (j) {setTimeout(function timer() {console.log(j);}, j * 1000);})(i); // 把i作为参数传递给前面括号里的j
}

使用立即执行函数包裹 setTimeout 的回调函数,能够创建一个闭包
在上述代码中,首先使用了立即执行函数i 传入函数内部,这个时候值就被固定在了参数 j 上面不会改变,当下次执行 timer 这个闭包的时候,就可以使用外部函数的变量 j,从而达到目的。

  • 第二种就是使用 setTimeout 的第三个参数,这个参数会被当成 timer 回调函数的参数传入。
for (var i = 1; i <= 5; i++) {setTimeout(function timer(j) {console.log(j);},i * 1000,i);
}
  • 第三种就是使用 let 定义 i 了来解决问题了,这个也是最为推荐的方式
for (let i = 1; i <= 5; i++) {setTimeout(function timer() {console.log(i);}, i * 1000);
}

2. 变形题

/* TASK A1In the following code, what will be printed to console if a user clicks the first and fourth button? Why?
*/var nodes = document.getElementsByTagName("button");for (var i = 0; i < nodes.length; i++) {nodes[i].addEventListener("click", function () {console.log("You clicked element #" + i);});}

输出的是 nodes.length的值;

因为var生命的是函数作用域

解决:
方法1:let
方法2:闭包

 var nodes = document.getElementsByTagName("button");for (var i = 0; i < nodes.length; i++) {(function (i) {nodes[i].addEventListener("click", function () {console.log("You clicked element #" + i);});})(i);}
http://www.lryc.cn/news/439319.html

相关文章:

  • Java企业面试题3
  • 第3章C/C++流程控制
  • 这是一款很棒的AI录音机——Plaud NotePin,但是它注定失败
  • self-play RL学习笔记
  • 【机器学习】OpenCV入门与基础知识
  • JUC学习笔记(二)
  • 炫酷HTML蜘蛛侠登录页面
  • 算法里面的离散化
  • Https AK--(ssl 安全感满满)
  • ERROR: Failed building wheel for cython_bbox | pip install cython_bbox 失败【解决方案】
  • 逻辑与位运算的双面舞者:、、|、||深度解析
  • 中断门+陷阱门
  • RTMP直播播放器的几种选择
  • 初识爬虫1
  • 【趣学Python算法100例】兔子产子
  • HTTP 四、HttpClient的使用
  • C语言:结构体变量
  • bibtex是什么
  • 【大模型专栏—进阶篇】智能对话全总结
  • MVC应用单元测试以及请求参数的验证
  • 算法:TopK问题
  • .json文件的C#解析,基于Newtonsoft.Json插件
  • 四、(JS)JS中常见的加载事件
  • [网络]https的概念及加密过程
  • React 嵌套类名样式不生效
  • 20Kg载重30分钟续航多旋翼无人机技术详解
  • 详解c++:认识类
  • HTML5中的重要元素详解
  • 八股文知识汇总(常考)
  • unity 图片置灰shader