前端面试高频点之闭包

2022-12-22 0 504

序言

对后端合作开发技师来说,旋量群是两个极难搞清楚因此极为难吞并的两个基本概念!即使旋量群的聚合更为重要与表达式的codice有关因此与变[1] 量的合作开发周期也有著紧密的亲密关系。最终我能的确地说你,旋量群在前述合作开发的操作过程中应用领域极为广为,因此你要要掌控它。

先上看呵呵有关旋量群的表述:旋量群是指无权出访另两个表达式codice中的表达式的表达式。建立旋量群的常用形式,是在两个表达式外部建立另两个表达式。

//透过旋量群能赢得表达式fn的局部变量user function fn(){ var user = atguigu; return function(){ return user; }//透过非官方表达式回到codiceuser } console.log(fn()());//atguigu 透过box()()来间接初始化非官方表达式codice var b = fn(); console.log(b());//atguigu 另一类初始化非官方表达式codice

透过旋量群能同时实现表达式内的codice的加总:

function fn(){ var num = 100; return function(){ num ++; return num; } } var b = fn();//赢得表达式 //你会辨认出codicenum并没在缓存之中消亡 console.log(b());//初始化非官方表达式 console.log(b());//第三次初始化非官方表达式,同时实现加总

由于在旋量群所在的codice回到的局部表达式不会被销毁,因此会占用缓存。过度的使用旋量群会迫使性能下降,因此建议大家在有必要的情况下再使用旋量群。

codice链的机制会导致两个问题,在循环中的非官方表达式取得的任何表达式都是最终两个值function fn(){ var arr = []; //i为fn表达式中的codice。 for(var i = 0; i < 3; i++){ arr.push(function(){ returni; }); }return arr; } var b = fn(); for(var i = 0; i < b.length; i++){ console.log(b[i]());//3 }

以上示例输出的结果均是3,也是循环结束后i的值。这是即使在for循环的操作过程之中,数组中的非官方表达式并没自我执行。当在初始化非官方表达式的时候,透过旋量群赢得的i已经是3了,因此每次输出的都是3。

如果想要输出的结果为0,1,2能做如下的调整:function fn(){ var arr = []; for(var i = 0; i < 3; i++){ arr.push((function(num){ //将立即执行表达式回到的非官方表达式放到数组中。 //即使num为表达式的参数,因此有自己独立的codice return function(){ return num; }; })(i)); } return arr; } var b = fn(); for(var i = 0; i < b.length; i++){ console.log(b[i]());//0,1,2 }

透过非官方表达式的立即执行,将立即执行后回到的表达式间接赋值给数组arr。每次循环即将i的值传递给num,又即使num在表达式中,因此有自己的独立codice,因此num得到的值为每次循环传递进来的i值,即0,1,2

接下上看呵呵有关旋量群之中的this对象:

this对象指的是什么,这个要看表达式所运行的环境。如果表达式在全局范围内初始化 ,表达式内的this指向的是window对象。对象中的方法,透过旋量群如果运行的环境为window时,则this为window。即使旋量群并不是该对象的方法。

var color = “red”; function fn(){ return this.color; } var obj = { color:“yellow”, fn:function(){ return function(){//回到非官方表达式 return this.color; } } } console.log(fn());//red 在外部间接初始化this为window var b = obj.fn();//b为window下的表达式,赢得的值为obj对象下的fn方法回到的匿 名表达式 console.log(b());//red 即使是在window环境下运行,因此this指缶的是window //能透过call或apply改变表达式内的this指向 console.log(b.call(obj));//yellow console.log(b.apply(obj));//yellow console.log(fn.call(obj));//yellow

透过表达式能赢得上两个codice中的this指向

var color = “red”; function fn(){ return this.color; }var obj = { color:“yellow”, fn:function(){ var _this = this;//将this赋值给表达式_this return function(){ return _this.color;//透过_this赢得上两个codice中的this指向 } } } console.log(fn());//red var b = obj.fn(); console.log(b());//yellow

能透过构造方法传参来出访私有表达式

function Desk(){ var str = “”;//codicestr,默认值为”” this.getStr = function(){ return str; } this.setStr = function(value){ str = value; }; } var desk = new Desk(); //为构造表达式的codice写入值。 desk.setStr(“atguigu”); console.log(desk.getStr());//atguigu

旋量群常用的作用

1、模拟块级codice(非官方自执行表达式)

if () {},for () {} 等没codice,因此在其块内声明的表达式,在外部是能使用的。

//javaScript没块级codice的基本概念 function fn(num){ for(var i = 0; i < num; i++){} console.log(i);//在for外部i不会失败 } fn(2); if(true){ var a = 13; } console.log(a);//在if表述的表达式在外部能出访

透过非官方自执行表达式能模拟块级codice

(function(){ //i在外部就不认识啦 for(var i = 0; i < count; i++){} })(); console.log(i);//报错,无法出访

由于外部无法出访自执行表达式内的表达式,因此在表达式执行完后会立刻被销毁,在外部无法出访。从而可有效避免在多人合作开发时由于全局表达式过多而造成的命名冲突问题。另外由于codice链的机制,codice要比全局表达式的出访速度更快,能提升程序的运行速度!

2、对结果进行缓存

写两个用于同时实现所有参数和的表达式:

var fn = function(){ var sum = 0; for(vari =0; i < arguments.length; i++){ sum += arguments[i]; } return sum; } console.log(fn(1,2));//3

以上表达式接收一些number类型的参数,并回到这些参数之和。由于每次传递的参数相同,因此回到的结果是一样的。这样势必会造成了一类浪费,在此时咱们能透过缓存机制来提高这个表达式的性能。

varfn = (function(){ var cache = {}//将结果缓存到该对象中 return function(){ var str = JSON.stringify(arguments); if(cache[str]){//判断缓存中是否存在传递过来的参数,存在间接回到结果, 无需计算 return cache[str]; }else{//进行计算并回到结果 var sum = 0; for(var i = 0; i <arguments.length; i++){ sum += arguments[i]; } return cache[str] = sum; } } })()

上面的示例将计算后的结果缓存到codicecache之中,在初始化这个表达式时,先在缓存中查找,如果找不到,则进行计算,然后将结果放到缓存中并回到,如果找到了,间接回到查找到的值。

最终我们总结知道,旋量群解决了以下两个问题:

1. 能读取表达式外部的表达式

2. 让这些表达式的值始终保持在缓存中。不会在表达式初始化后被清除

但同时,旋量群也有它的缺点:

1. 由于旋量群会是的表达式中的表达式都被保存到缓存中,滥用旋量群很容易造成缓存消耗过大,导致网页性能问题。解决方法是在退出表达式之前,将不再使用的codice全部删除。

2. 旋量群能使得表达式外部的值能在表达式外部进行修改。因此,如果你把父表达式当作对象(object)使用,把旋量群当作它的公用方法(Public Method),把外部表达式当作它的私有属性(private value),这时一定要小心,不要随便改变父表达式外部表达式的值。

了解更多内容:

后端安全有关复试题

后端JS高阶复试题

后端项目性能优化-复试题

后端ES6低频复试题

后端设计模式-复试题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务