闭包

闭包理解

如何产生闭包

  • 当一个嵌套的内部(子)函数引用了嵌套外部(父)函数的变量(函数)时--就产生了闭包

闭包是什么

  • 使用chrome调试查看

  • 理解一 -- 闭包是嵌套的内部函数

  • 理解二 -- 闭包是包含被引用变量(函数)的对象

  • 闭包存在于嵌套的内部函数中

  • 产生闭包的条件

  • 函数嵌套

  • 内部函数引用了外部函数的数据(变量或函数)

<script>
    function fn1() {
        var a = 3;
        function fn2() {
            console.log(a);
        }
        fn2();
    }
    fn1();
</script>

闭包

常见闭包

将函数作为另一个函数的返回值

function fn1() {
    var a = 2;
    function fn2() {
        a++;
        console.log(a);
    }
    return fn2;
}
var f = fn1();
f();    //3--fn1的返回值是fn2--相当于调用了fn2()--相当于fn1()()
f();    //4--闭包不会消失--第一次fn1()执行时--闭包内的数据是3--第二次执行时就是4

将函数作为实参传递给另一个函数调用

function showDelay(msg, time) {
    setTimeout(function () {
        console.log(msg);   //闭包
    }, time);
}
showDelay('zao', 2000);

闭包

闭包的作用

  • 使用函数内部的变量在函数执行完后--仍然存活在内存中--延长了局部变量的生命周期

  • 让函数外部可以操作(读写)到函数内部的数据--变量/函数

问题

  • 函数执行完--函数内部声明的局部变量是否还存在--一般不存在,存在于闭包中的变量才可能存在
  • 在函数外部能直接访问函数内部的局部变量吗--不能,但可以通过闭包让外部操作它

闭包的生命周期

  • 产生--在嵌套内部函数定义执行完时就产生了
  • 死亡--在嵌套内部函数成为垃圾对象时
function fn1(){
    // 闭包产生--函数提升--内部函数已经创建了
    var a = 2;
    function fn2(){
        a++;
        console.log(a);
    }
    return fn2;
}
//只要有变量引用fn1()闭包就一直存在
var f = fn1();
f();
f();
//闭包死亡--包含闭包的函数成为垃圾对象
f = null;

闭包的应用

定义JS模块

  • 具有特定功能的js文件
  • 将所有数据和功能都封装在一个函数内部--私有
  • 只向外暴露一个包含n个方法的对象或函数
  • 模块的使用者--只需通过模块暴露的对象调用方法来实现对应的功能
//JS文件
function myMoudle() {
    var msg = 'zaoya';
    function doSomething() {
        //toUpperCase--字符串转换为大写
        console.log('doSomething()' + msg.toUpperCase());
    }
    function doOtherthing() {
        //toLowerCase--字符串转换为小写
        console.log('doOtherthing()' + msg.toLowerCase());
    }
    //向外暴露对象
    return {
        doSomething: doSomething,
        doOtherthing: doOtherthing
    }
}

//html文件
<script src="myMoudle.js"></script>
<script>
    let fn = myMoudle();
	fn.doSomething();
	fn.doOtherthing();
</script>
//JS文件
(function myMoudle1() {
    let msg = 'zaozao';
    function doSomething() {
        console.log('doSomething()' + msg.toUpperCase);
    };
    function doOtherthing() {
        console.log('doOtherthing()' + msg.toLowerCase);
    }
    window.myMoudle1 = {
        doSomething: doSomething,
        doOtherthing: doOtherthing
    }
})()

//html文件
<script src="myMoudle1.js"></script>
<script>
	myMoudle1.doSomething();
	myMoudle1.doOtherthing();
</script>

闭包的缺点

缺点

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

解决

  • 能不用闭包就不用闭包
  • 及时释放

内存溢出

  • 一种程序运行出现的错误
  • 当程序运行需要的内存超过了剩余的内存时--就会抛出内存溢出的错误

内存泄漏

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

常见内存泄漏

  • 意外的全局变量
  • 没有及时清理的计时器或回调函数
  • 闭包

面试题

var name = 'The Window';
var object = {
    name: 'My Object',
    getNameFunc: function () {
        return function () {
            return this.name;
        }
    }
}
//object.getNameFunc()--是对象调用--通过object调用--this为object
//通过object.getNameFunc()--调用函数--object.getNameFunc()()--是函数调用--this为window
alert(object.getNameFunc()());  //The Window
var name2 = 'The Window';
var object = {
    name2: 'My Object',
           var that = this;
        return function () {
            return that.name2;
        }
    }
}
//object.getNameFunc()--是对象调用--通过object调用--this为object
//object.getNameFunc()()--中that是object.getNameFunc()的this--指向object
alert(object.getNameFunc()())       //My Object

原文链接:https://www.cnblogs.com/Liu-h/p/17352722.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:闭包 - Python技术站

(0)
上一篇 2023年4月25日
下一篇 2023年4月27日

相关文章

  • jQuery表格插件datatables用法详解

    jQuery表格插件datatables用法详解 简介 datatables是一款非常流行的jQuery表格插件,它具有高度的灵活性和扩展性,可以帮助开发者方便地生成丰富交互性的数据表格。datatables支持多种数据源和接口,可以与各种服务器端语言如PHP、Java、.Net等进行交互。datatables还拥有众多强大的扩展插件,可用于实现排序、过滤、…

    JavaScript 2023年6月10日
    00
  • 用python找出那些被“标记”的照片

    下面是用Python找出被“标记”的照片的完整攻略。 步骤1:安装依赖库 在使用Python进行图像处理时,需要安装一些依赖库,如OpenCV、Pillow、numpy等。可以使用pip等方式进行安装。 !pip install opencv-python !pip install opencv-contrib-python !pip install Pil…

    JavaScript 2023年5月28日
    00
  • BootstrapValidator验证用户名已存在(ajax)

    让我来为你详细讲解“BootstrapValidator验证用户名已存在(ajax)”的完整攻略。 标题 首先,我们需要给这个攻略起个标题。根据内容,可以考虑起名为“BootstrapValidator验证用户名已存在(ajax)”。 说明 为了实现这个功能,我们需要用到以下内容: BootstrapValidator插件 Ajax请求来检查用户名是否已存在…

    JavaScript 2023年6月10日
    00
  • 原生JS实现数码表特效

    原生 JS 实现数码表特效攻略 概述 该攻略是使用原生 JS 实现数码表特效的完整教程。该特效是指数字从 0 变化到目标数字,即数码表翻滚特效。 实现步骤 首先,我们需要在 HTML 中创建一个数码表的结构,包括外层容器和数字容器。HTML 结构如下: <div class="counter"> <div class=&…

    JavaScript 2023年6月11日
    00
  • Javascript图像处理—为矩阵添加常用方法

    Javascript 图像处理 – 为矩阵添加常用方法 前言 在图像处理中,矩阵是重要的数据结构。Javascript 作为一门强大的编程语言,可以非常方便地完成矩阵的各种操作。在本篇文章中,我们将讲解为矩阵添加一些常用方法的过程,以便于以后的图像处理中使用。 实现常用矩阵方法 为了方便起见,我们在这里定义一个矩阵的类: class Matrix { con…

    JavaScript 2023年6月11日
    00
  • 17个JavaScript 单行程序

    JavaScript 是一门非常重要的编程语言,具有广泛的应用。在网上,有很多有趣的JavaScript 单行程序,它们虽然只有一行代码,但是实现的功能很有趣。接下来,我来为大家详细讲解 “17个JavaScript 单行程序”的完整攻略,希望对大家学习JavaScript编程有所帮助。 先列出这 17 个单行程序: 在控制台输出一个笑脸 ? 反转字符串 统…

    JavaScript 2023年5月18日
    00
  • 基于Two.js实现星球环绕动画效果的示例

    以下是 “基于Two.js实现星球环绕动画效果的示例”的完整攻略: 1. Two.js简介 Two.js是一款轻量级的渲染工具库,可以轻松使用它来创建2d图形和动画。 2. 创建场景和画布 这个示例的第一步是使用Two.js创建一个场景和画布。 // 创建画布 var two = new Two({ fullscreen: true, autostart: …

    JavaScript 2023年6月11日
    00
  • JavaScript字符串包含问题

    JavaScript字符串包含问题是指在一个字符串中,查找是否包含另一个字符串的问题。通常使用indexOf()或includes()方法来解决该问题。 使用indexOf()方法 indexOf()方法返回字符串中指定字符或字符串第一次出现的位置。返回值为-1表示未找到。可以通过以下方式使用它来判断一个字符串是否包含另一个字符串: let str = ‘h…

    JavaScript 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部