2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 什么是闭包?优缺点分别是什么?

什么是闭包?优缺点分别是什么?

时间:2023-01-24 07:51:35

相关推荐

什么是闭包?优缺点分别是什么?

目录

1、举例子

2、什么是闭包?

3、闭包的优点

4、闭包的缺点以解决方法

5、闭包的两道经典题

1、举例子

最简单的两个闭包例子:

// 闭包1(function(a){console.log(a) // 1})(1)

// 闭包2function fn(){var a = 2return function(){console.log(a) // 2}}fn()()

2、什么是闭包?

闭包:可以访问另一个函数作用域变量的函数。由于javascript的特性,外层的函数无法访问内部函数的变量;而内部函数可以访问外部函数的变量(即作用域链)

由于在 Javascript 语言中,只有函数内部的子函数才能读取该函数的局部变量,因此可以把闭包简单理解成 “定义在一个函数内部的函数”。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以在函数外部读取内部的变量,另一个就是让这些变量的值始终保持在内存中。

闭包:在局部作用域引用上层作用域(非全局)的变量

3、闭包的优点

隐藏变量以及防止变量被篡改和作用域的污染,从而实现封装

4、闭包的缺点以解决方法

函数执行完后,函数内的局部变量没有释放,占用内存时间变长,容易造成内存泄漏。

由于保留了作用域链,会增加内存的开销。因此需要注意内存的使用,并且防止内存泄露的问题。

解决方法:

让内部函数变成垃圾对象,赋值为null,及时释放,让浏览器回收闭包

// 闭包3function fn1() {var b1 = 1var c1 = 2// 这个函数就是个闭包,可以访问外层 a 函数的变量return function() {var d1 = 3return b1 + c1 + d1}}console.log(fn1()()) // 6console.log(b1, c1, d1) // b1 is not defined

var test = (function(a) {console.log('第二步执行', a) // 1this.a = areturn function(b) {console.log('调用后的第三步',b) // 4return this.a + b}})((function(a, b) {console.log('第一步执行', a, b) // 1,2return a})(1, 2))console.log(test(4)) // 5

5、闭包的两道经典题

题目一:

var name = "the window";var obj = {name : "myObject",// 属性getNameFunc:function(){// 方法return function(){return this.name;};}};alert(obj.getNameFunc()()); // 输出了 “the window”;

答案: 输出了全局 the window,为什么不是对象属性 myObject 呢?

解法:形成一个闭包环境,需要两个条件:函数嵌套,子函数引用父函数局部变量,但是上面的例子,我只看到了函数嵌套,但没看到子函数引用父函数局部变量,所以这个函数嵌套根本就产生不了闭包环境,所以他不是个闭包。

调用 alert(obj.getNameFunc()()),注意,他有两个 () () ,调用第一个 () 时,实际上就是执行了getNameFunc()这个函数,但这个函数又嵌套了 return function(){ return this. name },

所以执行第一个括号时,就是执行了 return function(){ return this. name },到执行第二个 () 时,才是真正执行到了第二个函数的内部了,也就是 return this.name 了,但由于这个函数方法,他不是个闭包环境,所以 this 指向了 window 了,也就是 var name = “the winodw” ;

题目二:

var name2 = "the window";var obj2 = { name2:"my name is a obj",getNameFunc2 :function fn1(){var that = this; return function(){return that.name2; };}}alert(obj2.getNameFunc2()()); // 输出 my name is a obj

这次是输出的是 对象内的属性了,因为这次的才是真正的闭包环境,有函数嵌套,有父函数变量给子函数引用,形成依赖关系,产生闭包环境。

父函数明确定义了局部变量,var that = this;然后这个 that 呢,他又被子函数所引用,当 alert(obj2.getNameFunc()()) 执行时,就是执行子函数内部的 return that.name,

先在自身查找有没有 that.name,没有就返回上一层父函数,找到了 var that = this 了,这个就是闭包的环境。当然,两个函数执行域内都没有这个变量属性时,再往上一层,

也就是obj2对象内的属性,有个 name,终于在对象的执行域找到了,那就输出了 对象name的属性值。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。