1.闭包-面试重灾区

最近面试的过程中,但凡问到JavaScript闭包的时候,一脸懵逼的情况的占多数。

闭包这个东西,你说它重要吧,确实很重要,毕竟这是很多前端框架广泛使用的开发技巧。你说他不重要吧,也确实没那么重要,因为我们开发项目基本都是套用现有的框架,在框架的范围里面写代码,很少会用到闭包。

可是,耐不住面试经常要问啊。

这一节,我们就来聊聊闭包的话题!

2.什么情况会产生闭包

先看一个例子:
function f(){ let a = 1; return function(){ console.log(a); } } f()()
a是函数f内部的一个变量,按理说函数结束后,外面就没法访问到a了。

可是假如我们用一个函数访问到a,然后再把这个函数返回出去,就延续了a的生命周期。

上面代码的结果是1。

不仅如此,我们还可以在外面反复地操作a。

3.闭包将产生幽灵般的鬼魅变量

上面的例子中,我们把a变量悄悄地送出了函数f,接下来我们可以对它进行反复蹂躏!
function f(){ let a = 1; return function(increment){ a += increment;
console.log(a); } } f()(1)
答案是2,可见,我们可以在外面对a变量进行操作。下面思考一个问题,假如我多次操作会怎样?
var inner = f(); inner(1); inner(1); inner(1);
答案

 可见,多次操作的话,操作的是同一个a变量,这个a变量就如同鬼魅一般,你在外面看不到他,他却真实存在着。

4.闭包可以和对象结合起来用

直接看下面的例子,有一定的实战意义
var obj = {} function f(){ let a = 1; obj.num = a; obj.get = function(){
return a; } obj.set = function(v){ a = v; } } f()
这个代码和之前的有不同,它没有在函数f中直接返回另一个函数,而是给外面的obj对象赋予了一些属性和方法,很神奇吧,可这是语法允许的。

函数f被运行后,那么obj.num的值想必大家一看就知道是1

那假如我这么做呢?
obj.num += 1;
 这样一来,obj.num就等于2

但是obj.get()得到的值是多少?

还是1,这是因为a是基本类型的数字1,而 obj.num = a 其实是值拷贝,我们没法通过改变num的大小去同步改变a,他们是两个变量了。而 obj.get
,obj.set 操作的才是真正的a

上面我们说 a是基本类型的数字1,而 obj.num = a 其实是值拷贝 ,那如果a是对象类型,就可以操作了。
let a = {}; obj.a = a; obj.get = function(){ return a; } obj.set =
function(v){ a = v; }

好了,从这个例子中,我们不难发现,闭包的最大作用就是延续函数内部某些变量的生命周期。但是也正因为此,闭包可能会引发一些内存泄漏的问题。不过,大部分情况,这点内存泄漏真的无伤大雅。

可能有的同学会说,我不用闭包也可以啊,大不了在obj里面设置一个属性a,一样的。

在这个例子中,确实是的。

可是,在某些特殊的时候,用闭包是真的很有必要。

5.闭包的实战 - Vue数据绑定 

在Vue中,我们知道,会有一个初始化过程,这个过程会对data中的所有属性进行挟持,以便触发watcher更新。以下是简化的代码
var data = { username:'', password:'' } for(let key in data){
Object.defineProperty(data,key,{ set(v){ data[key] = v }, get(){ return
data[key] } }) }
这个代码乍一看没啥问题,可是当我们给username赋值,就会触发set方法

 报错是因为发生了循环引用,set被重复触发。

同样的,get也会报错

 

 这可怎么办,我们是不是必须得有一个临时变量,来保存当前属性的value呢?

像这样
for(let key in data){ let value = data[key] Object.defineProperty(data,key,{
set(v){ value = v }, get(){ return value } }) }

瞬间完美了。

 按理说,value是for循环中的一个临时变量而已,因为用的是let,所以只在当前作用域有效。而这个临时的value因为被set和get方法访问到了,于是其生命周期也得以延续!

所以,我对闭包的理解就是:函数访问了外部的变量,并且这个函数会在未来的某个时刻用到这个变量,就是闭包。

技术
©2019-2020 Toolsou All rights reserved,
C语言——qsort函数CSS实现溢出显示省略号网络层协议——ICMP协议C语言小游戏-俄罗斯方块Qt入门教程【基础控件篇】QCalendarWidget日历控件用python来控制wifi连接vue中input框只能输入数字Python内置函数C语言数据结构-顺序表删除重复V2.0.0abaqus质量缩放系数取值_ABAQUS的质量缩放