javascript闭包学习

闭包,逆战(疫情)中学习的Lx

  1. 闭包的概念
    闭包(Closure)的概念比较抽象,闭包是能够读取其他函数内部变量的函数。我理解,闭包可以在函数内部定义的函数,继承定义的函数的变量。能够有自己独立的作用域。
    2.一个简单的闭包例子
function a(){
	var i = 1
	function b (){
	console.log(i++)
	}
	return b
}
const c = a()
c()
c()
c()

这个一个简单的闭包,因为函数b使用了函数a的变量,在b的作用域链上有一个变量i,定义后可以有自己单独的作用域,在函数执行完毕后没有被释放,属于b的作用域。
因此执行后在c函数的b自己独立的作用域内的i,因此c执行一次,每次作用域上的i就会+1,自己独立的作用域,因此闭包会造成内存泄露,不被释放,比较耗内存。最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
例如 c函数执行的结果为c函数的结果
c中保存的b使用了a函数中的i,单独作用域,因此没有被释放。当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造 成内存泄露。 内存泄漏就是内存占用,内存被占用的越多,内存就变得越来越少了,就像内存被 泄露了一样 。
3.比较a函数的返回值

    function a(){
         let i = 1
         function b(){
             console.log(i++)
         }
         return b
     }
     const c = a()
     const d = a()
     console.log(c === d)

结果为
在这里插入图片描述
这个是由于a()执行后返回的函数的地址都是不同的,因此作用域也是独立的。

	 c()
     c()
     c()
     d()
     d()

c调用三次,d调用两次
在这里插入图片描述
c和d的执行上下文是不同的,因此,相互之间是不会影响。每次都是独立的执行上下文,同时,由于每次调用都是在上一次的基础上增加,可见函数c的执行完成后还是没有完全被释放,因此会造成内存的泄露。
下面在通个一个例子来进行讲解闭包

    function a(){
        var b = []
        for(var i = 0;i<5;i++){
            b[i] = function(){
                console.log(i)
            }
        }
        return b
    }
    c = a()
    console.log(c)
    c.forEach((item,index) => {
        item()
    });

该函数已经形成了闭包。变量i的值会跟随函数b保存到外面,因此,c中的内存不会被释放,第一完成后i的值从0一直加到5,指导5不符合条件。当函数c调用的时候,作用域内的i已经变成了5。因此打印结果是5个5。
在这里插入图片描述
在这里插入图片描述此处可以利用立即执行函数来解决该问题。

    function a(){
        var b = []
        for(var i = 0;i<5;i++){
           (function(i){
                b[i] = function(){
                    console.log(i)
                }
           }(i))
        }
        return b
    }
    c = a()
    console.log(c)
    c.forEach((item,index) => {
        item()
    });

由于立即执行函数,每次执行都会生成一个独立的空间来存放i,因此每次执行i分别成0到4被村春进去,档b[i]被执行的时候,就会使用立即执行函数中的i来进行输出。
在这里插入图片描述

发布了7 篇原创文章 · 获赞 1 · 访问量 84

猜你喜欢

转载自blog.csdn.net/qq_40944052/article/details/104458961