JS 经典闭包面试题

JS 经典闭包面试题1 带参闭包问题 functionfoo x vartmp 3 returnfuncti y alert x y tmp varbar foo 3 bar 现在是一个闭包 bar 10 注 首先执行 varbar foo 3 那么 foo 就执行了 参数 3 也传进去了 但是

1.带参闭包问题

function foo(x) { var tmp = 3; return function f2(y) { alert(x + y + (++tmp)); }; } var bar = foo(3); // bar 现在是一个闭包 bar(10); 

:首先执行var bar = foo(3);那么foo就执行了,参数3也传进去了,但是执行完毕后,tmp变量以及参数x就已经被释放回收了吗?
并没有,因为返回值里面还等待使用这些变量,所以此时,foo虽然执行了,但是foo的变量并没有被释放,在return中等待继续使用这些变量,这时bar就是一个闭包。

2.事件闭包问题
例:很多元素绑定一个点击事件
点击每个按钮时拿到当前按钮所对应的索引值
CSS样式如下:






       

首先看拿不到在for循环里当前对象的i值的写法:

var btn = document.getElementsByClassName("btn"); for (var i = 0; i < btn.length; i++) { btn[i].onclick = function () { alert(i); } } 

注:网页初始化时,每个按钮的事件都已经绑好了,用户触发都是后续触发的,后续触发说明事件有了,事件有了说明for循环执行完成,i就已经拿到最大值
问题:怎样在for循环里拿到当前对象的i值
解决:索引对索引
写法一:参数的传递






var btn = document.getElementsByClassName("btn"); for (var i = 0; i < btn.length; i++) { //参数的传递 桥梁 btn[i].index = i; btn[i].onclick = function () { alert(this.index); } } 

写法二:自执行函数的闭包 自执行函数的参是后面跟括号里的参数传的

var btn = document.getElementsByClassName("btn"); for (var i = 0; i < btn.length; i++) { (function (x) { btn[i].onclick = function () { alert(x); } })(i); //这个i是for循环的i } 

:for循环每一次都执行一个自执行函数,每一次变量i被当做参数传到IIEF(自执行函数)中去,那么这个IIEF中创建了一个变量参数x,然后元素节点btn绑定了一个onclick事件,执行函数里面需要用到这个参数x,但是你又没点,那么这个变量x就没有被清理,就一直在参数里面被保存着,每一个IIEF都做一样的事情,所以这个时候就产生了闭包,变量x并没有被回收,依然在等待使用。

3.面向对象

function fun(n, o) { console.log(o) return { fun: function (m) { return fun(m, n); } }; } var a = fun(0); a.fun(1); a.fun(2); a.fun(3); var b = fun(0).fun(1).fun(2).fun(3); var c = fun(0).fun(1); c.fun(2); c.fun(3); 
function f1(a, b, c) { console.log(arguments[0]); //4 console.log(arguments.length); //3 } f1(4, 5, 6); 

例:

function f1(a, b, c) { /*arguments 是当前函数的参数列表 类似于数组的集合 使用索引值来取*/ console.log(arguments.length); } f1(1, 2, 3); var sum = function () { var cache; if (arguments.length === 1) { cache = arguments[0]; //如果arguments对象的长度为1,也就是参数只有1个时,将这个参数赋值给cache,暂存 return function (number) { //返回一个函数,函数里的参数(也就是第二个括号里的参数)与之前第一个括号里的参数相加 return cache + number } } else { return arguments[0] + arguments[1]; //如果arguments对象的长度不为1,那么两个参数相加 } } console.log(sum(2, 3)); //5 console.log(sum(2)(3)); //5 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/179030.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午3:59
下一篇 2026年3月26日 下午3:59


相关推荐

  • 磁盘清理中的Windows更新清理

    磁盘清理中的Windows更新清理在清理 c 盘的系统文件时 会有一个 Windows 更新清理可勾选项 且一般会占较大内存空间 默认为不勾选 那是否可以勾选 用处 Windows 保留通过 Windows 更新安装知的所有更新的副本 甚至在安装了新版本的更新后 Windows 更新清理将删除或压缩不再需要的旧版本更新以免占道用空间 可能需要重新启动计算机 因此可以删除

    2025年10月9日
    5
  • docker容器端口冲突_docker web管理工具

    docker容器端口冲突_docker web管理工具COMMAND_FAILED:’/sbin/iptables-tnat-A Docker -ptcp-d0/0–dport8111-jDNAT–to-destination172.17.0.6:8111!-idocker0’failed:iptables:Nochain/target/matchbythatname.pk

    2022年8月31日
    10
  • 三极管的饱和导通条件[通俗易懂]

    三极管的饱和导通条件[通俗易懂]请看图,假设三极管基极电流为1MA,三极管直流放大倍数为50,那么在三极管集电极就有50MA电流。这时如果RL取100Ω,那么在RL两端分得电压5V,而另5V就加在三极管上,这时三极管处于正常放大状态。如果RL取300Ω呢?根据计算。在RL上应该分得15V电压。如果电源电压超过15V,那么这个电路仍处于放大壮态。可这里电源电压只有10V,那么这10V电压几乎全加在了电阻上,而三极管…

    2022年6月29日
    94
  • petalinux-package_centos7安装详细图解

    petalinux-package_centos7安装详细图解PetalLinux是Xilinx公司推出的嵌入式Linux开发工具,专门针对Xilinx公司的FPGASoC芯片和开发板,用户可以在PetaLinux工具的帮助下进行完整的开发流程,包括设计,验证,仿真,下载等。本文将详细介绍PetaLinux的安装流程,虽然实际上基本就是把Xilinx的UG1144翻译一遍。

    2025年10月26日
    4
  • PHP中__FUNCTION__与__METHOD__的区别

    PHP中__FUNCTION__与__METHOD__的区别

    2021年10月15日
    43
  • 无需科学上网!免费GPT-4 IDE工具Cursor完整使用指南

    无需科学上网!免费GPT-4 IDE工具Cursor完整使用指南

    2026年3月16日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号