简单说 一道JS闭包面试题

由一道面试题来深入理解闭包 有这么一道不太难的面试题,做出这道题应该是轻轻松松,但是想要了解这道题本身考察的知识点,就需要仔细的研究一下: let x = 1; function A(y){ let x = 2; function B(z){ console.log(x+y+z); } return B; } let C = A(2); C(3); 按照闭包的概念,上面的例子中,函数套函数,子级函数里面用了父级函数的变量,这种情况就属于闭包 打印结果是7 1、let C = A(2)调 阅读详情

说明

最近看到这样一段代码

 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);
 //问:三行a,b,c的输出分别是什么?

觉得有点意思,和大家一起来聊聊。
我相信如果你不是非常理解JavaScript中的闭包,一定是不想看这段代码的。

解释

好的,我们暂时先不去想这段代码,先看点简单的

function fun0(){
    var a=1;
    console.log(a);
}
function fun1(){
    console.log(a);
}
fun0(); //1
fun1(); //报错 a is not defined

这段代码,我相信大家应该知道最后为什么结果会是 1 和 报错 的,在函数内声明的变量只在函数体内定义,它们是局部变量,作用域是局部的,所以 函数 fun1 调用后,找不到a,就报错了,JavaScript采用词法作用域,函数的执行依赖于变量作用域,这个作用域是在函数定义时决定的,所以我们只要改改上面函数 fun1的位置,它就不会报错了。

function fun0(){
    var a=1;
    console.log(a);

    //把fun1放在fun0中,就不报错了
    function fun1(){
        console.log(a);
    }
    fun1();   //1
}
fun0();   //1

代码改成这样,只是把fun1 放在 fun0 中就不报错了,函数调用后都输出1

好了,我们来看最开始提到的代码,先简化一下

function fun(n,o){
    return {
    }
}

我们先看这段代码,fun 调用后会怎么样?
很明显会返回一个空对象,记住,fun调用后会返回对象,这点很重要。

 function fun(n,o){
    console.log(o);
    return {
        fun:function(m){
            return fun(m,n);
        }
    };
 }

 var a = fun(0);

这里提一句,当调用函数的时候传入的实参比函数声明时指定的形参个数要少,剩下的形参都将设置为undefined值。
console.log(o); 输出undefined
var a = fun(0); 那a是值是什么,是fun(0),返回的那个对象

{
    fun:function(m){
        return fun(m,0);
    }
}

这个对象,有一个fun的方法,方法返回的结果就是最外面 fun 调用的结果。

这里写图片描述
var a=fun(0),传入一个参数0,那就是说,函数fun中参数 n 的值是0了,而返回的那个对象中,需要一个参数n,而这个对象的作用域中没有n,它就继续沿着作用域向上一级的作用域中寻找n,最后在函数fun中找到了n,n的值是0,这段话是本文的重点, 明白这段,那问题就容易解决了。

说到这里,这道题基本上可以解决了,希望大家能听明白我上面说的话,下面的就简单了。我们一步一步看。

现在我们知道 a 是

{
    fun:function(m){
        return fun(m,0);
    }
}

这样的一个对象
a.fun(1); 会怎么样?看代码

{
    fun:function(1){
        return fun(1,0);
    }
}

a.fun(1); 返回的结果,就是 fun(1,0),返回的结果

 function fun(n,o){ //n的值为1,o的值为0
        console.log(o);
        return {
            fun:function(m){
                return fun(m,n);//n的值为1
            }
        };
}
fun(1,0);  //输出0,并返回一个对象,这个对象有一个fun的方法,这个方法调用后,会返回外层fun函数调用的结果,并且外层函数的第二个参数是 n 的值,也就是1  

a.fun(2); 会怎么样?看代码

{
    fun:function(2){
        return fun(2,0);
    }
}

a.fun(2); 返回的结果,就是 fun(2,0),返回的结果

 function fun(n,o){ //n的值为2,o的值为0
        console.log(o);
        return {
            fun:function(m){
                return fun(m,n); //n的值为2
            }
        };
}
fun(2,0); //输出0,并返回一个对象,这个对象有一个fun的方法,这个方法调用后,会返回外层fun函数调用的结果,并且外层函数的第二个参数是 n 的值,也就是2  

a.fun(3); 就不说了,一样的。

var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);

我们继续说b,b和a的不同在于,var a = fun(0); 之后一直用的是a这个对象,是同一个对象,而b每次用的都是上次返回的对象。
如果改成这样

var a = fun(0); a=a.fun(1); a=a.fun(2); a=a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);

把返回的对象,重新赋值给a,这样两行的结果就是一样的了。
var c = fun(0).fun(1); c.fun(2); c.fun(3);
c 与他们的不同,只是var c = fun(0).fun(1); 之后用的是同一个对象罢了。

总结

说下结果

var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
//undefined 0 0 0 

var b = fun(0).fun(1).fun(2).fun(3);
//undefined 0 1 2

var c = fun(0).fun(1); c.fun(2); c.fun(3);
//undefined 0 1 1

最开始的代码来自这里
http://www.cnblogs.com/xxcanghai/p/4991870.html

这篇文章只是针对这道题讲了讲,没有非常着重的去讲闭包这个概念,所以如果朋友们,对闭包详细的概念还不是很理解,要赶紧学习了。
顺便推荐几篇讲解闭包的文章

学习Javascript闭包(Closure)
Javascript闭包——懂不懂由你,反正我是懂了
JS闭包可被利用的常见场景

这里写图片描述

js之闭包经典面试题 //1.下面代码执行后的结果是?如何处理 var arr = []; for(var i = 0;i<10;i++){ arr.push(function () { console.log(i); }) }//[function(){},function(){},function(){},function(){}。。。。] arr[6](); //i是几 10 // //由于for... 阅读详情

相关推荐

一不小心就做错的JS闭包面试题

由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧。 先看题目代码: 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);//undefined,?,?,? var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,? var

JavaScript 回调函数面试题

回调函数 直接上题: function fun(n, o) { console.log(o); return { fun: function(m) { return fun(m, n); } }; } var a = fun(0); a.fun(1); a.fun

苛性钠的博客 906

Win10系统VS2019+Cmake+qhull_8.0.0环境配置

1 qhull 1.1 简要介绍 qhull是一个强大的计算几何库,可以用于计算高维的convex hull, Delaunay triangulation, Voronoi diagram等。 1.2 依赖库 qhull不依赖其他库。 1.3 源码包下载 qhull源码地址:github:https://github.com/qhull/qhull.git 2 Cmake构建项目 2.1 路径 源代码路径:D:/ThirdParty/qhull/qhull_8.0.0构建项目路径:D:/Thi.

wangchenxue的博客 2493

JavaScript - 闭包经典练习题2 - ‘套娃’

function fun (n,o){ console.log(o); return { fun:function(m){ return fun(m, n); }; }; }; var c = fun(0).fun(1); c.fun(2); c.fun(3); 解析步骤: 全局上下文中进行变量提升。

wendyGao_Yin的博客 1112

从零到一:Qt与PCL的跨平台开发环境搭建全攻略

本文详细介绍了从零开始搭建Qt与PCL跨平台开发环境的完整流程,涵盖Windows、Linux和macOS三大平台。重点解析了Qt5与Qt6版本选择、PCL库安装配置、VTK集成等关键技术要点,并提供跨平台CMake项目模板和常见问题解决方案,助力开发者快速构建三维点云处理应用。

weixin_29280657的博客 384

【Linux】实际项目应该如何完成?--安防监控系统项目的总结

到目前为止我也做个5、6个嵌入式项目,但以往都是从零开始自己做,也就是毫无计划,想到那里做那里,有想法就会去实现,就这样导致我碰到了很多坑,也消耗了我许多时间,当然,不是说这样不好,因为在其中我也得到了一个很好的锻炼与练习,但是这不适用于在工作中去这样做。...

修成真的博客 6729

经典面试题分析

题目 function fun(n, o) { console.log(o) return { fun: function(m) { return fun(m, n); } }; } var a = fun(0); //undefined a.fun(1); //0 a.fun(2); ...

weixin_42535771的博客 1584

最小二乘拟合圆:使用拉格朗日乘子法

在本文中,我们将探讨如何使用拉格朗日乘子法来进行最小二乘拟合,并将其应用于拟合一个空间圆。首先,我们需要定义问题。给定一组二维或三维数据点,我们的目标是找到一个圆,使得这些数据点到圆的距离的平方和最小。为了找到最小值,我们需要计算拉格朗日函数的偏导数,并令其等于零。通过解决优化问题,我们可以找到最佳拟合的圆,以最小化数据点到圆的距离的平方和。其中,(x, y) 是圆心的坐标,r 是圆的半径,(xi, yi) 是数据点的坐标。其中,g(x, y, r) = 0 是约束条件,C 是常数,λ 是拉格朗日乘子。

TechProX的博客 475

JS闭包经典面试题

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);//undefined,?,?,? var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,? var c = fun(0).fun(1); c.fun(.

weixin_47212352的博客 414

raw (R/G, B/G) 色度域从白点筛选到 mired 直方图的完整构建流程

raw 域用draw​δraw​筛出白点后,。,与 CIE uv 域流程逐步对应。

大熊 40

【推荐100个unity插件】unity易于使用模块化设计的天空、体积云和天气系统——Enviro 3

Enviro 3是一款功能强大的Unity天空与天气系统插件,提供动态天空、体积云、天气模拟等丰富功能。安装时需将预制体拖入场景并配置主相机,URP支持需激活深度纹理和添加渲染特性。模块化设计允许自由添加/移除时间、光照、雾效等模块,并通过API控制参数。推荐配合色调映射(如ACES模式)获得最佳视觉效果。插件支持季节、温湿度模拟及闪电风暴等特效,适用于需要逼真环境渲染的Unity项目。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2094

一篇常做错的经典JS闭包面试题

作者 | Jeskson 来源 | 达达前端小酒馆 1 究竟是怎么样的一道面试题,能让我拿出来说说呢?下面请看代码: function fun(a,b) { console.log(b) return { fun: function(c) { return fun(c,a); } }; } var d = ...

程序员哆啦A梦,蓝胖子 3384

智能车图像处理20-进阶篇12--正入十字补线1

这篇文章主要讲述基本的正入十字补线方法。

taiyuezyh的博客 6950

嵌入式Linux系统级安全加固实战:裁剪、权限、审计、防火墙四板斧

随着物联网设备大规模部署,嵌入式Linux设备面临的安全威胁日益严峻。攻击者往往利用系统默认配置、开放端口、调试接口等漏洞实施入侵,而设备缺少专职运维人员,一旦被攻破便难以快速响应。安全加固的核心在于减少暴露面并建立有效的防护机制。通过内核与根文件系统的最小化裁剪,可以大幅降低攻击面;配合权限硬化、日志审计与轻量防火墙策略,能够实现从启动到运行的全链路防护,让设备即使暴露在网络中也不易被攻破。这套方法适用于工业控制、智能网关、远程运维等场景,帮助开发者在量产前构建一套可落地、可长期维护的安全基线,为设备上线

weixin_33801856的博客 348

【基于深度学习的脑电图识别】数据集篇:THE TUH EEG CORPUS: A Big Data Resource for Automated EEG Interpretation

【基于机器学习的脑电图识别】数据集篇:脑电信号自动判读的大数据摘要: 摘要: 这个数据集包括超过 25000 个脑电图研究,包括一个神经学家对测试的解释,一个简短的病人病史和关于病人的人口统计信息,如性别和年龄。这是第一次有足够的数据来支持最先进的机器学习算法的应用。在这篇论文中,我们使用了3762个语料库的会话子集,展示了从原始脑电图信号数据预测脑电图的一些基本属性的初步实验结果。在闭环测试中,...

梁瑛平的博客 5615

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

JavaScript闭包-面试题

什么是闭包? 闭包(closure)指有权访问另一个函数作用域中变量的函数 ----JavaScript高级程序设计 简单来说,闭包就是一个函数(一个作用域可以访问另一个函数的局部变量) 闭包的作用是什么? 延伸变量的作用范围 function fn() { var num = 10; return function() { console.log(num); //这里的num就是访问了fn()函数的局部变量num,所以fn()是一个闭包函数 } } var f =

Var-al 的博客 1438

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

js打印线程id_一道经典JS面试题(闭包+异步)

今天在这里给大家分享一道 JavaScript(JS)的经典面试题。昨天,和往常一样逛着知乎,看到一篇文章名为《如果你想靠前端技术还房贷,你不能连这个都不会》吸引到了我,文章里的作者出了两道题来面试几十个 三年经验以上 的前端工程师,第一题就有很多人答错,第二题更是很多人选择放弃。由于第一题涵盖很多JS基础,所以今天我在这里给大家分享下第一道经典面试题:for 我先不给出答案,大家来分析下,最后输...

weixin_39761822的博客 217

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

大部分人都会做错的经典 JS 闭包面试题

作者:小小沧海https://www.cnblogs.com/xxcanghai/p/4991870.html由工作中演变而来的面试题这是一个我工作当中的遇到的一个问题,似乎很有趣,就当...

zz_jesse的博客 725

js闭包经典面试题的代码

先看三段被称为js闭包经典面试题的代码 第一种引起for循环问题的原因 // 异步引起的for循环问题 1 for(var i=0;i<5;i++){ setTimeout(function timer(){ console.log(i); },i*1000); // 异步引起的for循环问题 2 for (var i = 1; i <= 5; i++) ...

TENCENTSYS的博客 1767

一道JS前端闭包面试题思路解析

题目来源与参考https://segmentfault.com/a/1190000004187681 function fun(n,o){ console.log(o); return { fun:function(m){ return fun(m,n); } } } var a=fun(0);// undefined...

mus-z的博客 448

图解JavaScript闭包面试题

由于最近在学习关于闭包相关的知识,并且闭包这个知识点让我有点搞不太清楚其具体的定义,所以在网上也查阅了很多大佬的讲解和对闭包的一个定义。 最后感觉还是MDN上的说法感觉比较好理解一些,对闭包还是不太理解的道友可以尝试看一看。 MDN上是这样说的:闭包是函数和声明该函数的词法环境的组合 原地址:https://developer.mozilla.org/zh-CN/docs/W...

ONE0101的博客 287

【JS面试题】如何通过闭包漏洞在外部修改函数中的变量

闭包这个东西对新人来说确实挺头疼的,MDN官方表述是这样的。闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建确实不是很好理解,那么我来通俗讲一下。闭包其实就是指在函数内部定义一个函数,内部定义的函数可以访问外部函数作用域中的变量,这样就形成了一个封闭的作用域,被称作闭包。

m0_62360527的博客 1663

js $ 不存在_一道经典JS面试题(闭包+异步)

今天在这里给大家分享一道 JavaScript(JS)的经典面试题。昨天,和往常一样逛着知乎,看到一篇文章名为《如果你想靠前端技术还房贷,你不能连这个都不会》吸引到了我,文章里的作者出了两道题来面试几十个 三年经验以上 的前端工程师,第一题就有很多人答错,第二题更是很多人选择放弃。由于第一题涵盖很多JS基础,所以今天我在这里给大家分享下第一道经典面试题:for ( var i = 0 ; i &l...

weixin_42361026的博客 106

【 JS面试题 】关于闭包

本文作者从一道经典的JS面试题,分享了自己对JS闭包的理解。 作者:IT程序狮 链接:https://www.jianshu.com/p/7ff589e78964 先看题目代码: 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);//undefined,?

Kelly_yml的博客 353

你要会的,js闭包前端面试题

有工作经验的前端都知道,面试时基本都会问下js闭包问题,考查下你的js基础水平。作为新手前端刚入门的你,这个前端面试必备知识点,你会吗?不会的话,就赶快看下吧,补补课吧。 1.闭包的概念: 闭包就是一个函数,两个函数彼此嵌套,内部函数就是闭包形成闭包条件是内部函数需要通过return给返回出来。 看下面的代码,你就懂了: 1 2 3 4 ...

web前端开发博客 1万+

闭包的一道面试题

来一道面试题 让我们先来复习一下闭包的概念,闭包就是外部函数嵌套一个内部函数,并且内部函数引用外部函数的局部变量,这样的结构构成闭包。 由于闭包的存在,所以外部函数执行完毕后,内部函数引用的变量不会被gc(内存回收机制)回收 <!DOCTYPE html> ...

chuntianni1600的博客 151
上一篇: 简单说 CSS中的mask—好好利用mask-image
下一篇: 简单说 正则表达式——要注意lastIndex属性
FEWY
FEWY 领域专家: 前端开发技术领域 领域专家: 前端开发技术领域
博客等级 码龄10年 504粉丝 77原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值