<
>

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

2022-04-15 14:49:00 来源:易采站长站 作者:

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

前言:

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

一、作用域

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

function f1(){  let n = 999  console.log(n)}f1() // 999function 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()) // 2console.log(g()) // 3console.log(g()) // 4console.log(g()) // 5

2、setTimeout函数传递参数

默认的setTimeout是这样的:

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

小编也曾经这样试验过

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="externole.log(c.finalNum) // 3

参考文章:

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

https://www.cnblogs.com/pikac...

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

暂时禁止评论

微信扫一扫

易采站长站微信账号