当前位置: 首页 > Web前端 > HTML

我所知道的闭包

时间:2023-04-02 11:14:04 HTML

(~ ̄(OO) ̄)プ,闭包,面试中的一个老问题,迷茫了很久。慢慢不断的对自己有了一点认识,在此分享~~~废话不多说,先看题:varoutput=(function(){varx=y=7;return[function(){console.log(x)},function(){console.log(y);}]})();for(vari=0;i<2;i++){output[i]();}控制台.log(++y);控制台日志(++x);结果是什么???大家可以先自己想想,再听我分析(下车)(#^.^#);首先,我们从for循环开始,循环两次,执行outputp[0]();outputp[1]();首先outputp会返回一个数组,数组中有两个方法,所以outputp[0]();outputp[1]();将执行数组中的两个方法。这就涉及到闭包的知识了~~~第一次听说闭包,别人给我的解释是函数在函数中输出。哈哈,简单粗暴的理解,但是,没错,这确实形成了一个闭包。关于闭包,不得不说到javascript的范围。我们都知道js无非就是全局变量和局部变量。在js中,函数内部可以访问全局变量的值,但函数外部无法获取内部值。但是有一个方法可以帮助我们从外部取回内部的值,没错,就是这个闭包~~~先继续看这道题,下面一步步讲解。这是函数内部的返回函数,形成一个闭包。所以我们可以从外部获取x和y的值。没错,我们可以使用outputp[0]();输出p[1]();得到它,即会打印77;为什么一般的函数可以,没有return的时候,函数执行完就关闭了是的,但是闭包会返回一个函数,所以这个函数是不能关闭的,所以我们可以利用这个特性,就是我认为是闭包。(萌新,没意见);继续看最后两行console.log(++y);控制台日志(++x);这里我们回到varx=y=7;依此类推y=7;varx=y;所以,y实际上是一个全局变量。x是局部变量。console.log(++y)会输出8,因为全局变量可以在任何地方访问console.log(++x)会报UncaughtReferenceError:xisnotdefined可能有同学会问,既然闭包也是x的值还在内存中,为什么访问不到呢?因为我们之前说过,函数外部是无法获取到内部值的,所以直接调用x是获取不到的。闭包使用outputp[0]()的返回,output函数调用其parent的值x,即可得到y。考虑闭包有什么用?本梦心在实战中用过几次,但毕竟缺乏经验。这里我只说两点。for(vari=0;i<8;i++){setTimeout(function(){console.log(i)},500)}这将输出8个8,这是一道糟糕的面试题。如何输出0/1/2/3/4/5/6/7?只需将vari更改为leti。没有es6语法怎么办?这样:for(vari=0;i<8;i++){(function(i){setTimeout(function(){console.log(i);},1000);})(i);}这也是利用了闭包的原理,可以在函数内部查看父函数的值,因为父函数有子函数,所以每次for循环中i的值都在内存中,并没有改变。第二点是利用闭包的特性来增加某些密钥的安全性。比如有一条很重要的留言“楼主真是个机灵的小鬼”。在一个函数内部,我们想到了在外部使用它,但是我们不希望任何人都可以随便调用它,因为这个信息非常重要。所以我们可以这样做:functiongetKey(){varkey="楼主真是个小机灵鬼";return{_xxx:(function(){returnkey;})()}};console.log(getKey()._xxx)key我们想全局调用,又不想同事调用。_xxx可以是一个加密的字符串,我可以这样写,这样我就可以全局使用了。这是我小白对闭包的理解,请指出(如有错误请指出);最后祝大家身体健康,谢谢~~~