Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【前端芝士树】Js中的闭包是怎么一回事 && 笔试问题集锦

【前端芝士树】Js中的闭包是怎么一回事 && 笔试问题集锦

作者头像
CloudCat
发布于 2022-05-06 07:35:08
发布于 2022-05-06 07:35:08
23800
代码可运行
举报
运行总次数:0
代码可运行

【前端芝士树】Js中的闭包是怎么一回事 && 笔试问题集锦

为什么会有闭包的出现?

这涉及到var作为变量声明的关键词时所出现的一些问题。 比如,var 的 变量提升 以及 函数级作用域

Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。 另一方面,在函数外部自然无法读取函数内的局部变量。

需要注意的是,如果在函数内部声明变量时没有使用var关键词,实际上声明的是一个全局变量,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function f1(){
    n = 999;
}
//console.log(n); // ReferenceError: n is not defined
f1();
console.log(n); // 999

这里为什么第一处会报错呢?关于这个问题下面有比较基础的解释:

JS的解析过程分为两个阶段:预编译期(预处理)执行期

  • 预编译期 JS会对本代码块(两个script块互不影响)中的所有var声明的变量和函数进行处理(类似与C语言的编译) 此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值。>
  • 执行期 会按照代码块的顺序筑行执行

正因为从外部访问在函数内部进行声明的局部变量是不可能的,所以出现了闭包这种形式,在函数内部再定义一个函数。

闭包(Closure)是什么?

查阅了一些文章和资料,发现还是下面的定义最容易理解:

闭包:定义在函数内部的一个函数。

扩展一些讲,可以参考一下阮一峰的讲解:

闭包:能够读取其他函数内部变量的函数。

俗话说的好,看定义不如看代码更直观一些,如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function f1(){
    var n=999;
    function f2(){
        console.log(n);
    }
    return f2;
}

var result=f1();
result(); // 999

如此段代码所示,f2()就是其中的闭包函数,通过f2()我们可以访问到f1()内部的n。 更常见的一种简写形式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function f1(){
    var n=999;
    return function(){
        console.log(n);
    };
}

var result=f1();
result(); // 999

闭包的优缺点

优点:

  1. 可以读取函数内部的变量
  2. 让这些变量的值始终保持在内存中。

缺点:

  1. 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
  2. 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

闭包面试题集锦(持续更新)

问题一、简单闭包
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var a = 1;
function foo(){
    var a = 2;
    c = 0;
    return function () {
        console.log(a);
        console.log(b++);
        console.log(c);
    }
}
console.log(a);// 1

//console.log(c); // Reference Error
var b = 3;
var x = foo();
x(); //2 3 0
console.log(a); // 1
console.log(b); // 4
console.log(c); // 0
问题二、闭包的链式调用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);

看解答前先思考一下会输出什么哦

【解答】: 首先对函数进行分析,这个函数其实是返回了一个对象,{fun:function(){}},里面有一个函数作为属性,这个函数就是闭包,使得函数内部的变量保留在内存中。

注意,这里会有一个可能误解的地方,return {fun:...}里面的fun是fun(n,o)吗?明白这个区别后后面就容易多了。

好了,明白大概的原理后,我们来分析这个问题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);

执行a = fun(0),0是作为n传入的,o没有参数传入,所以输出undefined,之后,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
a = {
  fun:function(m){
     return fun(m,0);//这里的n应该变成了第一次调用时的参数n,也就是0
  }
}
也就是
a = {
 fun:function(m){
     return function(n = m, o = 0) {
         console.log(o) //输出0
         return {
            fun:function(m){
              return fun(m,n);
            }
          };
    };
  }
}

所以无论传入的m是什么,输出永远都是0 最后,输出结果如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);
undefined
0
0
0

搞清楚第一个的过程,第二个的破解关键就在于闭包让函数内部的变量始终保存在内存之中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//b
undefined
0
1
2
//c
undefined
0
1
1

参考文章

《学习Javascript闭包(Closure) - 阮一峰的网络日志》 《闭包 - 廖雪峰的官方网站》

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
一道 js 闭包面试题的学习
最近看到一条有意思的闭包面试题,但是看到原文的解析,我自己觉得有点迷糊,所以自己重新做一下这条题目。
前端正义联盟
2018/08/14
7801
浅谈闭包
闭包 – closure, 应该可以说是javascript的一个难点吧, 其实说难也不难, 只是因为没有真正一个权威的人/书去给他一个真正的定义。 不过,学编程的人一路都要有自己的理解,很少人乐意去v死记一个定义。 自己看闭包也有很久了,但是每次回想起来又忘了自己改如何形容它, 它真的很难吗?其实并没有,每次看别人的博客,还是很快就能理清楚思路的, 于是终究还是要自己写下来,自己给自己一个理解。
用户1394570
2018/08/08
3640
JavaScript闭包实例讲解
闭包是JavaScript语言中的难点,很多刚入行的(包括我在内)一时对他很难理解,于是在网上各种搜罗有关闭包的学习资料,但是无数的文章介绍闭包,但都是了解一个皮毛。说实在的我到现在也不敢和大家百分百的肯定掌握它。所以今天我就把我的整理的学习笔记分享给大家,希望能够对大家有用。
ZEHAN
2020/09/23
6520
JavaScript闭包(Closure)
上面的代码中,函数 f2 就被包括在函数 f1 内部,这时 f1 内部的所有局部变量,对 f2 都是可见的。
Leophen
2019/08/23
5830
javaScript核心技术--“闭包”,不看绝对后悔!
“闭包”,又称“定义在函数内部的函数”,闭包技术是javaScript中很关键的核心技术,很多框架的研发或者企业高端技术都需要使用到它。要理解闭包技术,必须先弄明白“变量的作用域”。 1.变量的作用域 javaScript沿袭的java的变量规则,但稍有改进。和java一样可分为“全局变量”和“局部变量”,在javaScript中的“局部变量”又称之为函数变量。
Java深度编程
2020/06/10
3900
javaScript核心技术--“闭包”,不看绝对后悔!
56 道高频 JavaScript 与 ES6+ 的面试题及答案
用正则表达式匹配字符串,以字母开头,后面是数字、字符串或者下划线,长度为 9 - 20
Nealyang
2019/09/29
1.1K0
56 道高频 JavaScript 与 ES6+ 的面试题及答案
javascript中的闭包这一篇就够了
两段代码,在第二段代码中,函数A内的匿名函数可以访问到函数A中的局部变量这就是闭包的基本使用。
coder_koala
2019/07/30
6580
美团前端二面高频面试题合集
节流(throttle):触发高频事件,且 N 秒内只执行一次。这就好比公交车,10 分钟一趟,10 分钟内有多少人在公交站等我不管,10 分钟一到我就要发车走人!类似qq飞车的复位按钮。
loveX001
2022/09/13
2930
JavaScript闭包
IMWeb前端团队
2017/12/29
7490
闭包面试题原题_闭包 数学
② 第一个 fun 具名函数执行之后会返回一个对象字面量表达式,即返回一个新的object对象。
全栈程序员站长
2022/11/01
2740
闭包面试回答_ajax面试题
👸🏾:写在前面:在学习了闭包之后,试着做做这些题。其实是一种很棒地检验自己学习成果的手段。我当时反反复复,学了但好像又没完全学,遇到题还是一头雾水,到现在可以捋得很清楚也经历了蛮久的。而且从this,执行上下文,作用域一直走过来,这些题目涉及的内容也相对全面,加油喽。👍🏾 ​​​​​​​👉【JS基础整理—No.06】闭包_Chailo的博客-CSDN博客 //🍕 闭包面试题1 function show(){ f = function fn(){ console.log(x); } v
全栈程序员站长
2022/09/27
1960
【JS】重温基础:闭包
这里先要了解一个概念,词法作用域:它是静态的作用域,是书写变量和块作用域的作用域**。
用户1462769
2019/09/19
1.9K0
经典JS闭包面试题
大部分人都会做错的经典JS闭包面试题 目录 由工作中演变而来的面试题 JS中有几种函数 创建函数的几种方式 三个fun函数的关系是什么? 函数作用域链的问题 到底在调用哪个函数? 后话 由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧。 先看题目代码: function fun(n,o) { console.log(o) return { fun:function(m){ return
逸鹏
2018/04/09
1.7K0
经典JS闭包面试题
闭包初识
[详情参考](http://www.cnblogs.com/wangfupeng1988/p/3994065.html);
天天_哥
2018/09/29
2930
🌞 深入剖析 JavaScript 闭包
🌞 深入剖析 JavaScript 闭包 💎导读目录 什么是闭包 闭包的特性 闭包的优缺点 闭包的作用 闭包的注意点 💎什么是闭包? 一个函数和对其周围状态的引用捆绑在一起,这样的组合就是闭包. 通俗的说: 一个内层函数可以访问外层函数的作用域 就叫 闭包。 在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。 闭包的形成与变量的作用域以及变量的生存周期密切相关。 💎闭包的特性 函数嵌套函数 函数内部可以引用外部的参数和变量 参数和变量不会被垃圾回收机制回收 💎闭包的优缺点
程序员海军
2021/03/25
3960
🌞 深入剖析 JavaScript 闭包
深入贯彻闭包思想,全面理解JS闭包形成过程
谈起闭包,它可是JavaScript两个核心技术之一(异步和闭包),在面试以及实际应用当中,我们都离不开它们,甚至可以说它们是衡量js工程师实力的一个重要指标。下面我们就罗列闭包的几个常见问题,从回答问题的角度来理解和定义你们心中的闭包。
疯狂的技术宅
2019/03/28
7610
深入贯彻闭包思想,全面理解JS闭包形成过程
深入浅出JavaScript之闭包(Closure)
阅读目录 闭包-无处不在 闭包的概念 闭包的用途 闭包-封装 常见错误之循环闭包 思考题 闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。下面写下我的学习笔记~ 闭包-无处不在 在前端编程中,使用闭包是非常常见的,我们经常有意无意,直接或间接用到了闭包。闭包可以使传递数据更加灵活(比如处理一些点击事件) !function() { var localData = "lo
逸鹏
2018/04/11
5030
深入浅出JavaScript之闭包(Closure)
javascript 闭包详解
一、什么是匿名函数 创建一个函数并将它赋值给变量functionName,这种情况下创建的函数,即匿名函数。(函数表达式就是匿名函数) 二、闭包 1.什么是闭包? 闭包就是能够读取其他函数内部变量的函数。 只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。 我们只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗! function f1 () { var num = 1; function f2() { console.
柴小智
2018/04/10
5600
前端基础-JavaScript函数进阶
这种写法将一个匿名函数赋值给变量。这时,这个匿名函数又称函数表达式(Function Expression)
cwl_java
2020/03/26
5540
JavaScript学习总结(三)——闭包、IIFE、原型、函数与对象
一、闭包(Closure) 1.1、闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9;方法:找到所有的div,
张果
2018/01/04
1.6K0
JavaScript学习总结(三)——闭包、IIFE、原型、函数与对象
相关推荐
一道 js 闭包面试题的学习
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档