返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript闭包中难点深入分析
  • 385
分享到

JavaScript闭包中难点深入分析

JavaScript闭包JS闭包 2022-11-13 19:11:33 385人浏览 八月长安
摘要

目录初识闭包什么是闭包如何产生闭包产生闭包条件闭包的作用闭包的生命周期闭包的应用闭包的缺点及解决方法闭包案例初识闭包 闭包可谓是js的一大难点也是面试中常见的问题之一,今天开始梳理一

初识闭包

闭包可谓是js的一大难点也是面试中常见的问题之一,今天开始梳理一下闭包的知识,请诸君品鉴。

什么是闭包

闭包是嵌套的内部函数;内部函数包含被引用变量(函数)的对象。闭包存在于嵌套的内部函数中,例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来。当然如何直观的查看闭包可以通过chrome来查看,这里有个坑需要反馈一下,新版的chrome需要先调用fun2()才允许debugger,这样才能显示闭包。

<script>
    function fn1(){
        var a = 2;
        function fn2(){//执行函数定义就会产生闭包(不用调用内部函数)
            console.log(a);
        }
        //新版的chrome需要返回一下内部函数才会显示闭包
        return fn2()
    }
    fn1()
</script>

如何产生闭包

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

<script>
    // 将函数作为另一个函数的返回值
    function fn1(){
        var a = 2;
        function fn2(){//
            a++;
            console.log(a);
        }
        return fn2 //将一个内部函数作为一个外部函数的返回值返回
    }
    var f = fn1()
    //整个过程产生了一个闭包,主要看你产生了几个内部函数对象,调用了几次外部函数
    //闭包的特点就是函数内部的变量会一直存在于内存中,不会立即释放。
    f()//3   这里的f()是调用了内部函数
    f()//4
</script>

<script>
    // 将函数作为实参传递给另一个函数调用
    function showDelay(msg,time){
        //setTimeout 的第一个参数是函数,符合闭包的规则
        setTimeout(function(){
            alert(msg)
        },time)
    }
    showDelay('张三',2000)
</script>

产生闭包条件

函数嵌套;内部函数引用了外部函数的数据(变量/函数)。

闭包的作用

使用函数内部的变量在函数执行完毕后,仍然存活在内存中(延长了局部变量的生命周期);让函数外部可以操作(读写)到函数内部的数据(变量/函数)。

闭包的生命周期

产生:在嵌套的内部函数定义执行完时就产生了(不是在调用),死亡:在嵌套的内部函数称为垃圾对象时就死亡了。

<script>
    function fn1 () {
        //此时闭包就已经产生了(函数提升,内部函数对象已经创建了)
        var a = 2;
        function fn2 () {//
            a++;
            console.log(a);
        }
        return fn2 //将一个内部函数作为一个外部函数的返回值返回
    }
    var f = fn1()
    f()//3   
    f()//4
    f = null //闭包死亡(包含闭包的函数对象成为垃圾对象)
</script>

闭包的应用

定义JS模块(具有特定功能的js文件),将所有的数据和功能都封装在一个函数的内部(私有的),只向外暴露一个包含n个方法的对象和函数;模块的使用者只需要通过模块暴露的对象调用方法来实现对应的功能。

//myModule.js 文件
function myModule(){
    // 私有数据
    var msg = 'My Module'
    function showUpper(){
        console.log('showUpper' +msg.toUpperCase());
    }
    function showLow(){
        console.log('showLow' +msg.toLowerCase());
    }
    //向外暴露对象(给外部使用的方法)
    return {
        showUpper:showUpper,
        showLow:showLow
    }
}
//index.html文件
<script src="./myModule.js"></script>
<script>
    var module = myModule()
    module.showUpper()
    module.showLow()
</script>
 

我们也可以通过匿名函数来实现闭包,这样能很便捷的调用闭包里面的属性,虽然会达到我们想要的效果,但是可能会造成全局的变量名污染,建议使用第一种。

//myModule2.js文件
(function(){
    // 私有数据
    var msg = 'My Module'
    // 操作数据的函数
    function showUpper(){
        console.log('showUpper' +msg.toUpperCase());
    }
    function showLow(){
        console.log('showLow' +msg.toLowerCase());
    }
    //向外暴露对象(给外部使用的方法)
    window.myModule2 = {
        showUpper:showUpper,
        showLow:showLow
    }
})()
//index.js文件
<script src="./myModule2.js"></script>
<script>
    myModule2.showUpper()
    myModule2.showLow()
</script

闭包的缺点及解决方法

在我们使用闭包过程中,函数执行完后,函数内部的局部变量没有释放,占用内存时间会变长,容易造成内存泄漏,所以在日常开发中,尽量避免闭包的出现,或者要对局部变量及时释放。

<script>
    function fn1(){
        var arr = new Array[100000]
        function fn2(){
            console.log(arr.length);
        }
        return fn2
    }
    var f = fn1()
    f()
    //不用闭包或者回收闭包
    f = null//让内部函数成为垃圾对象 --> 回收闭包
</script>

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

<script>
    var obj = {}
    for(var i=0;i<10000;i++){
        obj[i]=new Array(1000000)
        console.log('------');
    }
</script>

内存泄漏:占用的内存没有及时释放,内存泄漏积累多了就容易导致内存溢出。常见的内存泄漏:意外的全局变量、没有及时清理的计时器或回调函数、闭包。

<script>
    //意外的全局变量
    function fn(){
        a = 10;
        console.log(a);
    }
    // 调用函数虽然能打印a,但是a并没有被释放掉。一不注意就设置了一个全局变量
    fn()
    //没有及时清理计时器或回调函数
    var intervalId = setInterval(function(){ //启动循环定时器后不清理
        console.log('--------');
    },2000)
    // clearInterval(intervalId)
    //闭包
    function fn1(){
        var a = 2 //闭包 a 并没有被释放掉
        function fn2(){
            console.log(++a)
        }
        return fn2
    }
    var f = fn1()
    f()
    // f = null 不执行这条语句,a的值一直在
</script>

闭包案例

<script>
    // 案例一:
    var name = "this is Window"
    var object = {
        name:"this is Object",
        getName:function(){
            return function(){
                return this.name
            }
        }
    }
    //闭包的this只能是全局,若在当前作用域中定义了this,就直接使用定义的this,若没定义,则需要一层层向外找,直到全局为止
    //本题是没有闭包的
    alert(object.getName()())//this is Window
    // 案例二:
    var name1 = "this is Window"
    var object1 = {
        name1:"this is Object",
        getName:function(){
            //定义的that形成了闭包,内部函数引用了外部函数的变量,而this指向的是object,所以返回的是object中的name1
            var that = this;
            return function(){
                return that.name1
            }
        }
    }
    alert(object1.getName()())// this is Object
</script>
<script>
    //没有使用闭包的话,数据是没有保留的,所以n传递给o之后,下次运算o值还是上次的值不会发生改变
    function fun(n,o){
        console.log(o);
        return{
            fun:function(m){
                return fun(m,n)
            }
        }
    }
    //在执行fun(0)之后,n被之前的n=0,一直被调用
    var a = fun(0); //闭包里面的n传入了0
    a.fun(1); 
    a.fun(2);
    a.fun(3)//undefined,0,0,0
    //链式执行会导致n的改变,n是前面函数执行的形参
    var b = fun(0).fun(1).fun(2).fun(3)//undefined,0,1,2
    //c.fun(2)、c.fun(3)都调用了fun(1)留下的闭包n
    var c = fun(0).fun(1); 
    c.fun(2); 
    c.fun(3)//undefined,0,1,1
</script>

到此这篇关于JavaScript闭包中难点深入分析的文章就介绍到这了,更多相关JS闭包内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript闭包中难点深入分析

本文链接: https://lsjlt.com/news/171038.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaScript闭包中难点深入分析
    目录初识闭包什么是闭包如何产生闭包产生闭包条件闭包的作用闭包的生命周期闭包的应用闭包的缺点及解决方法闭包案例初识闭包 闭包可谓是JS的一大难点也是面试中常见的问题之一,今天开始梳理一...
    99+
    2022-11-13
    JavaScript闭包 JS闭包
  • 一文剖析JavaScript中闭包的难点
    目录一、作用域基本介绍1. 全局作用域2. 函数作用域3. 块级作用域二、什么是闭包1. 闭包的基本概念2. 闭包产生的原因3. 闭包的表现形式三、如何解决循环输出问题1. 利用 I...
    99+
    2024-04-02
  • 闭包之谜:深入探讨 JavaScript 闭包的行为
    范围和作用域链 闭包的作用域链由以下作用域组成: 局部作用域:闭包函数自身的作用域,其中包含闭包中声明的变量。 闭包作用域:创建闭包的函数的作用域,其中包含闭包访问的变量。 全局作用域:浏览器窗口或 Node.js 全局环境。 闭包可...
    99+
    2024-03-14
    闭包
  • JavaScript闭包实例分析
    这篇文章主要讲解了“JavaScript闭包实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript闭包实例分析”吧!   JavaSc...
    99+
    2024-04-02
  • 分析JavaScript闭包特性
    这篇文章主要介绍“分析JavaScript闭包特性”,在日常操作中,相信很多人在分析JavaScript闭包特性问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”分析JavaSc...
    99+
    2024-04-02
  • 深入解析React Hooks 闭包陷阱
    目录正文什么是闭包陷阱?useState 中的闭包陷阱示例避免方法useEffect 的闭包陷阱示例避免方法通过闭包访问和更新 state从 React Hooks 源码看闭包陷阱正...
    99+
    2023-05-19
    React Hooks 闭包陷阱 React Hooks 
  • JavaScript闭包的示例分析
    小编给大家分享一下JavaScript闭包的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!闭包是JavaScript中的...
    99+
    2024-04-02
  • Javascript中return与闭包的示例分析
    这篇文章给大家分享的是有关Javascript中return与闭包的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、return的使用案例一:var a=1;...
    99+
    2024-04-02
  • JavaScript闭包实例代码分析
    这篇文章主要介绍了JavaScript闭包实例代码分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript闭包实例代码分析文章都会有所收获,下面我们一起来看看吧。什么是闭包?闭包的概念是有很多版本...
    99+
    2023-07-05
  • 分析css与javascript的重难知识点
    这篇文章主要讲解了“分析css与javascript的重难知识点”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“分析css与ja...
    99+
    2024-04-02
  • JavaScript深入理解作用域链与闭包详情
    目录深入作用域链与闭包作用域链[[Environment]]完善环境记录闭包函数实例什么是闭包变量绑定同一个闭包总结深入作用域链与闭包 为什么要把作用域链和闭包放在一起讲呢,它们有什...
    99+
    2024-04-02
  • Go 包管理机制深入分析
    前言随着 Go 语言的深入使用,其依赖管理机制也一直是各位 Gopher 热衷于探讨的话题。Go 语言的源码依赖可通过 go get 命令来获取,但自动化程度不高,于是官方提供了 Dep 这样的自动化批量管理依赖的工具。...
    99+
    2023-06-04
  • Javascript中的闭包知识点讲解
    本篇内容介绍了“Javascript中的闭包知识点讲解”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. ...
    99+
    2024-04-02
  • javascript中变量提升和闭包的示例分析
    这篇文章主要介绍了javascript中变量提升和闭包的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。我们先来看一个题目:<s...
    99+
    2024-04-02
  • PHP高级特性:深入解析闭包的奥秘
    答案: php 闭包是一种匿名函数,可以在定义作用域外访问变量。详细描述:闭包创建:使用 function 关键字创建,可以访问定义作用域内的变量。访问变量:闭包可从内部读取外部变量,访...
    99+
    2024-05-15
    php 闭包 作用域
  • 深入解析WordPress:功能与特点分析
    WordPress 是一款功能强大的开源内容管理系统(Content Management System,CMS),广泛应用于网站建设和博客发布。它具有丰富的功能和特点,成为许多用户选...
    99+
    2024-03-01
    功能 特点
  • Webpack完整打包流程深入分析
    目录前言一、准备工作二、初始化阶段2.1、读取与合并配置信息2.2、创建编译器(compiler)对象2.3、插件注册三、编译阶段3.1、创建 compilation 编译对象3.2...
    99+
    2022-12-10
    webpack打包的整个过程 webpack打包过程 webpack打包机制
  • 闭包的谜题:剖析 JavaScript 闭包中的常见问题
    闭包通过在内部函数中引用外部变量来捕获变量。当外部函数返回时,内部函数仍然可以访问这些外部变量,即使外部函数本身已被销毁。 问题 2:闭包的陷阱是什么? 内存泄漏:如果闭包持有对外部变量的引用,而外部变量又引用了一些大型对象,则即使外部函...
    99+
    2024-03-14
    闭包
  • Javascript闭包使用场景的原理分析
    这篇文章给大家分享的是有关Javascript闭包使用场景的原理分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、闭包Javascript中,只有函数内部的子函数才能读取局部变量,闭包就是能够读取其他函数内部...
    99+
    2023-06-25
  • JavaScript单一职责原则深入分析
    目录单一职责原则设计模式中的SRP原则何时应该分离职责违反 SRP 原则SRP 原则的优缺点单一职责原则 就一个类而言,应该仅有一个引起它变化的原因。在 JavaScript 中,需...
    99+
    2022-11-13
    JavaScript单一职责原则 JavaScript单一职责 JavaScript设计模式
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作