Java教程

函数和闭包

本文主要是介绍函数和闭包,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

函数和闭包

函数是一等公民

函数是一等公民,意思是函数时非常重要的。

函数可以做为另一个函数的参数,也可以做为另一个函数的返回值来返回。

js中函数中仍然可以定义函数,实现函数嵌套。

闭包

闭包 :包含两部分,函数和自由变量。

严格来说就是函数内部访问了外部的自由变量,这就是一个闭包。

代码执行过程

  //闭包
        function foo() {
            var name = 'wang';
            var age = 13;

            function baz() {
                console.log(name);
                console.log(age);
            }
            return baz;
        }

        var fn = foo();
        fn();
1.在堆中创建go对象, 并且创建了执行上下文栈

在这里插入图片描述

2.在执行上下文栈中创建了全局执行上下文

全局执行上下文中先预解析代码,foo为函数,foo会保存foo函数的地址,fn为变量,初始值为undefined

在这里插入图片描述

3.开始执行foo函数前先解析foo函数

执行foo函数会创建foo函数执行上下文,当前的vo对应的函数AO,因此会创建AO对象,预解析foo函数中的变量,baz指向函数baz函数的内存地址

在这里插入图片描述

真的的执行foo函数

执行代码后,name:wang , age:13 ,return baz 最终全局执行上下文接受到foo的返回值并赋给了fn,因此fn保存了baz函数对象的地址

在这里插入图片描述

foo函数执行完毕

foo执行完毕以后,相应的函数执行上下文会被销毁,正常情况下foo的AO对象也应该销毁,但此事baz函数的父级作用域指向的是foo的AO对象,所以不会被销毁。
在这里插入图片描述

执行fn函数

执行fn函数实际上是执行baz函数。首相,同样是创建baz函数执行上下文,创建baz的AO对象,因为没有定义变量,所以baz的AO对象为空,然后直接执行代码,打印name和age。因为当前AO对象中没有name和age属性,所以会从他的父级AO对象中查找name和age,查找都父级AO(foo)对象的name和age后,打印出来。

在这里插入图片描述

执行完fn函数

执行完fn函数以后,创建的函数执行上下文和AO对象都会被销毁。但foo的AO对象,因为一直有baz函数的parent scope 指向他,所以一直不会被释放。所有可能会出现内存泄漏,当我们不在使用它的时候可以通过 fn=null 来释放闭包,放置内存泄漏.

在这里插入图片描述

AO中不使用的变量

闭包可以访问外层AO的变量,使得外层AO不会被销毁,但是外层AO中不使用的变量,按道理应该不被销毁,因为整个AO都不会被销毁,但v8引擎做了优化,不适用的变量会被销毁,防止了内存泄漏。

function foo() {
    var name = 'wang';
    var age = 12;

    function baz() {
        debugger //设置断点
        console.log(name);
    }
    return baz;
}

var fn = foo();
fn();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5lWwwEu1-1633009655698)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20210920103048996.png)]

可以看出闭包Closure中只剩下name变量。
r fn = foo();
fn();


![在这里插入图片描述](https://www.www.zyiz.net/i/ll/?i=85d0e019bfb7495189939f5e27fde781.png#pic_center)

可以看出闭包Closure中只剩下name变量。
这篇关于函数和闭包的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!