iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >js中的函数嵌套和闭包详情
  • 152
分享到

js中的函数嵌套和闭包详情

2024-04-02 19:04:59 152人浏览 安东尼
摘要

目录一、作用域二、函数的返回值三、函数嵌套四、闭包五、闭包的实际应用1、隐藏内部变量名称和函数执行暂停2、setTimeout函数传递参数3、回调4、函数防抖六、使用类实现类似闭包中

前言:

今天就先和大家一起聊一聊我理解的闭包。在聊这个问题之前,先了解一下变量的定义域。
js中,变量定义域有全局作用域和局部作用域之说。es6中新出现的变量声明关键字,就是为了解决部分变量作用域混乱引入的。全局作用域在这就不谈了。主要说说函数的作用域。

一、作用域

简单一点说,函数的作用域,就是函数的花括号内部,先看两个例子,或许能对这个概念理解的更好一点


function f1(){
  let n = 999
  console.log(n)
}
f1() // 999

function f2(){
  let n = 999
}
alert(n); // 报错

二、函数的返回值

要说闭包之前,我得先说一下函数返回值。关于函数的返回值,小编也是年初才有了一个更深层次的理解。没有返回值的函数,执行之后会返回undefined,有返回值的函数,执行之后就变成了对应的返回值。就像这样


// 没有返回值的函数
function f1(){
  alert(666)
}
console.log(f1()) // 出现弹窗之后,在控制台输出undefind

// 存在返回值
function f2(){
  alert(666)
  return 'over'
}
console.log(f2()) // 出现弹窗之后,在控制台输出over。当然,可以返回字符串,也可以返回Bealon,还可以返回函数。

三、函数嵌套

在《重构——改善既有代码的设计》中,提出了js语法是允许函数内部嵌套函数的,但并不是所有的编程语言都可以的,所谓代码嵌套,就是在函数内部又有函数声明,

就像这样:


function outer(){
  let name = 'lilei'
  function inner(){
    console.log(name)
  }
}  

四、闭包

前面说明了在js中的局部变量作用域的问题,在实际项目中,就是需要在函数外部,访问函数内部的变量,这个时候,按照局部变量作用域的问题。似乎是不可能的,闭包的出现,解决了这个问题。


function outer(){
  let name = 'lilei'
  function inner(){
    return name
  }
  return inner
}

上面是一个典型的闭包函数,在使用这个闭包函数的时候,我们可以这样:


let g = outer()
console.log(g()) // lilei


至此,已经解决了在全局访问函数内的局部变量。但是小编在回家的路上在想,为了实现这个功能,是不是不用这个麻烦,我通过这样的函数,也是可以满足需求的。


function outer(){
  let name = 'lilei'
  return name
}

console.log(outer()) // lilei  


确实上面的代码和通过闭包最终在控制台输出的内容是一样的,那为什么还要引入闭包呢?小编也是想了接近一周才明白的,这就好比变量->函数->类,每层往上都是逐步提升的过程,通过函数可以实现更多的逻辑,比如对数据进行处理,仅仅靠变量是不能实现的。

五、闭包的实际应用

上面小编介绍了闭包,那么在实际项目中有什么应用呢?先看下面代码:

1、隐藏内部变量名称和函数执行暂停


function outer() {
    let name = 1
    function inner() {
        return name ++
    }
    return inner
}
let g = outer()
console.log(g()) // 2
console.log(g()) // 3
console.log(g()) // 4
console.log(g()) // 5

2、setTimeout函数传递参数

默认的setTimeout是这样的:

小编也曾经这样试验过


function f1(p) {
    console.log(p)
}
setTimeout(f1(666),3000) // 并没有延时,直接输出666

要想通过延时来实现对函数传递参数,这时候,闭包的作用就显现出来了。


function f1(a) {
    function f2() {
        console.log(a);
    }
    return f2;
}
var fun = f1(1);
setTimeout(fun,1000); // 一秒之后打印出1

3、回调

  定义行为,然后把它关联到某个用户事件上(点击或者按键)。代码通常会作为一个回调(事件触发时调用的函数)绑定到事件。就像下面这块代码


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试</title>
</head>
<body>
    <a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  id="size-12">12</a>
    <a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  id="size-20">20</a>
    <a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  id="size-30">30</a>

    <script type="text/javascript">
        function changeSize(size){
            return function(){
                document.body.style.fontSize = size + 'px';
            };
        }

        var size12 = changeSize(12);
        var size14 = changeSize(20);
        var size16 = changeSize(30);

        document.getElementById('size-12').onclick = size12;
        document.getElementById('size-20').onclick = size14;
        document.getElementById('size-30').onclick = size16;
</script>
</body>
</html>

4、函数防抖

  在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

   实现的关键就在于setTimeout这个函数,由于还需要一个变量来保存计时,考虑维护全局纯净,可以借助闭包来实现。就像下面这样:



function debounce(fn,delay){
    let timer = null    //借助闭包
    return function() {
        if(timer){
            clearTimeout(timer) //进入该分支语句,说明当前正在一个计时过程中,并且又触发了相同事件。所以要取消当前的计时,重新开始计时
            timer = setTimeOut(fn,delay) 
        }else{
            timer = setTimeOut(fn,delay) // 进入该分支说明当前并没有在计时,那么就开始一个计时
        }
    }
}

六、使用类实现类似闭包中隐藏内部变量功能

上面是一个关于闭包的实际应用,小编在晚上睡不着觉的时候,想起同样的需求,是不是也可以通过类来实现呢?最后经过一顿折腾,答案是肯定的,就像这样:


class Adder{
    constructor(c){
        this._c = c
    }
    increace(){
        this._c ++ 
    }
    decreace(){
        this._c --
    }
    get finalNum(){
        return this._c
    }
}
let c = new Adder(1)
c.increace()
console.log(c.finalNum) // 2
c.increace()
console.log(c.finalNum) // 3
c.increace()
console.log(c.finalNum) // 4
c.decreace()
console.log(c.finalNum) // 3

参考文章:

https://www.cnblogs.com/gg-qq...

Https://www.cnblogs.com/pikac...

https://developer.mozilla.org...

--结束END--

本文标题: js中的函数嵌套和闭包详情

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

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • js中的函数嵌套和闭包详情
    目录一、作用域二、函数的返回值三、函数嵌套四、闭包五、闭包的实际应用1、隐藏内部变量名称和函数执行暂停2、setTimeout函数传递参数3、回调4、函数防抖六、使用类实现类似闭包中...
    99+
    2024-04-02
  • python中的函数嵌套和嵌套调用
    目录函数嵌套和嵌套调用函数的嵌套函数的嵌套调用函数中定义函数在函数内部定义的函数要在函数内部调用函数内的函数可以引用外部变量试图对外部变量进行修改函数怎么修改外部变量的值的说明函数嵌...
    99+
    2024-04-02
  • python3--函数名本质,函数嵌套,闭包,装饰器
    python函数的嵌套和作用域链函数的嵌套调用def max2(x,y):     m = x if x > y ...
    99+
    2023-01-30
    函数 嵌套 本质
  • Python函数中闭包和延迟绑定详情
    闭包必须满足以下3个条件: 必须有一个内嵌函数内嵌函数必须应用外部函数的变量外部函数的返回值必须是内嵌函数 关于请看下面代码: def multipliers(): return [...
    99+
    2024-04-02
  • Python中的嵌套循环详情
    目录1 什么是嵌套循环2 Python 嵌套 for 循环2.1 嵌套循环打印图案2.2 在 for 循环中的while循环2.3 实践:打印一个带有 5 行 3 列星形的矩形图案3...
    99+
    2024-04-02
  • Python函数的嵌套详解
    Python允许在函数中定义函数,这通常被称为嵌套函数或者内部函数。 def speak(text): def my_lower(t): return t.l...
    99+
    2024-04-02
  • 如何使用Python中的内嵌函数和嵌套作用域
    如何使用Python中的内嵌函数和嵌套作用域Python是一种功能强大的编程语言,它为开发者提供了许多有用的功能和工具。其中,内嵌函数和嵌套作用域是Python中的两个重要概念。本文将介绍如何使用这些概念,并提供具体的代码示例。在Pytho...
    99+
    2023-10-28
    作用域链 Python内嵌函数 嵌套作用域
  • c++中函数的定义和调用可以嵌套吗
    可以。c++ 允许函数嵌套定义和调用。外部函数可定义内置函数,内部函数可在作用域内直接调用。嵌套函数增强了封装性、可复用性和作用域控制。但内部函数无法直接访问外部函数的局部变量,且返回值...
    99+
    2024-05-06
    c++ 作用域 封装性
  • 如何使用Python中的内嵌函数和闭包实现一个计数器
    如何使用Python中的内嵌函数和闭包实现一个计数器Python作为一种功能强大的编程语言,提供了很多灵活的工具和技术,使得开发过程变得简单而高效。其中,内嵌函数和闭包是Python中非常重要的概念之一。在本文中,我们将探讨如何利用这两个概...
    99+
    2023-10-22
    闭包 计数器 内嵌函数
  • c++中函数的定义可以嵌套吗
    是的,c++ 中允许函数定义嵌套。函数嵌套指在一个函数内部定义另一个函数,嵌套函数能访问外部函数的作用域变量,优点包括模块化和简化数据访问,缺点包括代码难以维护、名称空间污染和堆栈溢出风...
    99+
    2024-05-06
    c++ 数据访问 作用域 堆栈溢出
  • 详解JS中的compose函数和pipe函数用法
    目录compose函数Array.prototype.reduceArray.prototype.reduceRightpipe函数compose函数 compose函数可以将需要嵌...
    99+
    2024-04-02
  • golang函数中的闭包机制
    闭包是一种仍然保留其作用域链但在函数执行完后仍然存在的函数。在 go 语言中,可以通过匿名函数和变量来实现闭包,它在函数内允许访问外部作用域中声明的变量,从而提供了封装数据和行为以及为不...
    99+
    2024-04-29
    golang 闭包 作用域
  • Python中的datetime包与time包包和模块详情
    目录一、datetime包1.timedelta(params…)得到一个时间增量对象2.timezone(timedelta) + timedelta(params&...
    99+
    2024-04-02
  • PHP 函数的链式调用和闭包
    是的,可以通过链式调用和闭包优化代码简洁性和可读性:链式调用可将函数调用链接为一个流畅接口。闭包可创建可重用代码块,并在函数外部访问变量。 PHP 链式调用和闭包:提升代码简洁性和可读...
    99+
    2024-04-13
    闭包 php 函数 链式调用 代码可读性
  • JavaScript闭包和匿名函数的关系
    这篇文章主要讲解了“JavaScript闭包和匿名函数的关系”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript闭包和匿名函数的关系”吧!前面...
    99+
    2024-04-02
  • golang函数闭包实现的详细指南
    函数闭包在 golang 中是可以访问和修改外部作用域变量的嵌套函数,在以下场景中很有用:状态管理:管理外部函数返回后仍存在的变量状态。对象建模:创建具有状态和行为的对象。上下文传递:将...
    99+
    2024-04-23
    go 函数闭包 golang 作用域
  • golang函数闭包和匿名函数之间的区别
    go 语言中的闭包和匿名函数的主要区别在于:闭包可以访问其创建范围之外的变量;匿名函数不能访问其创建范围之外的变量。 Go 语言中函数闭包和匿名函数之间的区别 闭包 闭包是一个函数,它...
    99+
    2024-04-24
    golang 闭包 匿名函数
  • Python函数和模块的使用详情
    目录一、定义函数二、函数的参数三、用模块管理函数四、变量的作用域 一、定义函数 在Python中可以使用def关键字来定义函数,命名规则跟变量的命名规则是一致的。在函数名后...
    99+
    2024-04-02
  • JS中不应该使用箭头函数的四种情况详解
    目录箭头函数的一些缺点1、不支持参数对象2、无法通过apply、call、bind来改变this指针什么时候不能使用箭头功能1、请不要在构造函数中使用箭头函数2、请不要在点击事件中操...
    99+
    2024-04-02
  • Python中的闭包和匿名函数有什么区别
    闭包和匿名函数都是函数的概念,但是它们有一些区别: 闭包是指在一个函数内部定义另一个函数,并且内部函数可以访问外部函数的变量。闭...
    99+
    2024-03-12
    Python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作