作用域和闭包的通俗理解(4)

死亡: 嵌套的内部函数成为垃圾对象时。(比如f = null,就可以让f成为垃圾对象。意思是,此时f不再引用闭包这个对象了)

闭包的应用:定义具有特定功能的js模块

将所有的数据和功能都封装在一个函数内部(私有的),只向外暴露一个包含n个方法的对象或函数。

模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能。

方式一

(1)myModule.js:(定义一个模块,向外暴露多个函数,供外界调用)

functionmyModule() {
    //私有数据
    var msg = 'Smyhvae Haha'

//操作私有数据的函数
    functiondoSomething() {
        console.log('doSomething() ' + msg.toUpperCase()); //字符串大写
    }

functiondoOtherthing() {
        console.log('doOtherthing() ' + msg.toLowerCase()) //字符串小写
    }

//通过【对象字面量】的形式进行包裹,向外暴露多个函数
    return {
        doSomething1: doSomething,
        doOtherthing2: doOtherthing
    }
}

上方代码中,外界可以通过doSomething1和doOtherthing2来操作里面的数据,但不让外界看到。

(2)index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>05_闭包的应用_自定义JS模块</title>
</head>
<body>
<!--闭包的应用 : 定义JS模块  * 具有特定功能的js文件  * 将所有的数据和功能都封装在一个函数内部(私有的)  * 【重要】只向外暴露一个包含n个方法的对象或函数  * 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能-->
<script type="text/javascript" src="https://www.linuxidc.com/myModule.js"></script>
<script type="text/javascript">var module =myModule();module.doSomething1();module.doOtherthing2();</script>
</body>
</html>

方式二

同样是实现方式一种的功能,这里我们采取另外一种方式。

(1)myModule2.js:(是一个立即执行的匿名函数)

(function () {
    //私有数据
    var msg = 'Smyhvae Haha'

//操作私有数据的函数
    functiondoSomething() {
        console.log('doSomething() ' + msg.toUpperCase())
    }

functiondoOtherthing() {
        console.log('doOtherthing() ' + msg.toLowerCase())
    }

//外部函数是即使运行的匿名函数,我们可以把两个方法直接传给window对象
    window.myModule = {
        doSomething1: doSomething,
        doOtherthing2: doOtherthing
    }
})()

(2)index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>05_闭包的应用_自定义JS模块2</title>
</head>
<body>
<!--闭包的应用2 : 定义JS模块  * 具有特定功能的js文件  * 将所有的数据和功能都封装在一个函数内部(私有的)  * 只向外暴露一个包信n个方法的对象或函数  * 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能-->

<!--引入myModule文件-->
<script type="text/javascript" src="https://www.linuxidc.com/myModule2.js"></script>
<script type="text/javascript">myModule.doSomething1()
    myModule.doOtherthing2()
</script>
</body>
</html>

上方两个文件中,我们在myModule2.js里直接把两个方法直接传递给window对象了。于是,在index.html中引入这个js文件后,会立即执行里面的匿名函数。在index.html中把myModule直接拿来用即可。

总结:

当然,方式一和方式二对比后,我们更建议采用方式二,因为很方便。

但无论如何,两种方式都采用了闭包。

闭包的缺点及解决

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

解决:能不用闭包就不用,及时释放。比如:

f = null;  // 让内部函数成为垃圾对象 -->回收闭包

总而言之,你需要它,就是优点;你不需要它,就成了缺点。

内存泄漏内存溢出 内存泄漏

内存泄漏:占用的内存没有及时释放。内存泄露积累多了就容易导致内存溢出。

常见的内存泄露:

1.意外的全局变量

2.没有及时清理的计时器或回调函数

3.闭包

情况1举例:

// 意外的全局变量
    functionfn() {
        a = new Array(10000000);
        console.log(a);
    }

fn();

情况2举例:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9fd4a7fc9889b57ba35c4e35b4b01968.html