闭包应用

news/2024/6/17 17:00:49

1.闭包含义

 

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <p>闭包就是一个对象,里面包含着一个函数,以及包含着一个被它捕获的变量</p>
    <script>
        function f1(){
            var a=1;
            var b=2;
            function f2(){//此时已经产生闭包了。f2的【scope】-->f1的词法环境(Lx)
                console.log(a);
            }
            f2();
        }
        f1();
    </script>
</body>
</html>

 

2.闭包应用之减少全局变量

 

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <p>闭包好处一:减少全局变量</p>
    <script>
        //1.有时当我们需要实现一个函数每调用一次都自增的效果,但是根据局部变量的垃圾回收机制,这个例子显然不能实现
//        function f(){
//            var a=1;
//            a++;
//            alert(a);
//        }
//        f();
//        f();
//        f();
        //2.于是我们把a设为全局变量,虽然效果实现了但是会导致全局变量过多,在大型项目中会产生命名冲突等一系列问题
//        var a=1;
//        function f(){
//            a++;
//            alert(a);
//        }
//        f();
//        f();
//        f();
        //3.而闭包却能解决这个问题,
        function f(){
            var a=1;
            return function(){
                a++;
                alert(a);
            }
        }
        var g=f();
        g();
        g();
        g();
        //至此,我们使用闭包解决了这个问题,由于局部变量在子函数中被引用,而使其不能被垃圾回收机制回收,并且由于子函数可以引用该变量,所以return子函数,就能在函数外部引用该变量了。只要不关闭浏览器不关闭该页面,函数外部就可以引用,这样的话a就不会被回收,值也就可以保存,也就可以递增
    //但是需要注意一个问题,闭包的存在会使得它不会被垃圾回收机制回收,它就会比其他函数占更多的内存,如果过渡使用闭包可能会导致内存占用过多。可能会导致浏览器崩溃的问题。那么解决的方法就是当已经达到我们需要达到的效果时,应该解除对匿名函数的引用,没有了引用,就变成了普通函数,就会被垃圾回收机制回收。
    </script>
</body>
</html>

 

3.闭包应用之减少减少传递给函数的参数的数量

 

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <p>好处二:减少传递给函数的参数的数量</p>
    <script>
        //实现下面这个例子需要两个参数,a为基数,b为在i自增后的和
//        function f(a,b){
//            var c;
//            var d=0;
//            for (var i=1;i<=b;i++){
//                d+=i;
//            }
//            c=a+d;
//            alert(c);
//        }
//        f(3,4);//弹出结果为3+(1+2+3+4)=13
        //下面这个例子采用闭包可以用一个参数实现同样的效果
        function f(a){//创建基础值函数,参数为a。(f函数其实相当于一个创建函数的工厂一样,它返回另外一个即其内部的函数)
            return function(b){//创建自增加函数并返回(这个函数作为其内部函数会引用其参数形成闭包)
                var c=0;
                for(var i=0;i<=b;i++){
                   c+=i;//for循环实现自增到参数b,并赋值给c
                }
                return c+a;//返回c与基础值的和
            }
        }
        var g=f(2);//将f()函数赋值给g,给f函数传入参数2,即基础值2.(其实就是把f函数的返回值即自增加函数赋值给g,说白了,单看f()函数时,就是f()函数,当把f()函数当作值赋值时,f()函数的值其实就是其内部return的函数)
        alert(g(3));
        alert(g(4));//此时弹出g函数,给g函数传入参数3,也就是给f函数的返回值即自增加函数传入参数3.
        //最终弹出结果为2+(1+2+3)=8. 2+(1+2+3+4)=12.
        var g1=f(3);//当然也调用多次f()函数赋值,每调用一次,改变一次基础值函数的参数值,产生一个新的闭包
        alert(g1(4));
        alert(g1(5));//结果为3+(1+2+3+4)=13. 3+(1+2+3+4+5)=18.
    </script>
</body>
</html>

 

4.闭包应用之封装

 

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <p>好处三:封装</p>
    <script>
        (function(){
             var m=0;
             function getM(){//得到m值
                 return m;
             }
             function setM(val){//设置m值
                 m=val;
             }
             window.g=getM;//为了在外部访问到,将其公布出函数外。
             window.s=setM;
         })();//自调用函数,将其封装
        s(10);//设置值为10
        alert(g());//得到弹出值为10
    </script>
</body>
</html>

 

转载于:https://www.cnblogs.com/forever-xuehf/p/8987505.html


http://www.niftyadmin.cn/n/1020557.html

相关文章

数据结构 --线性存储结构-数组、链表、栈、队列

学习目标&#xff1a; 理解数组、链表、栈、队列的实现原理&#xff0c;熟练线性存储结构的使用 学习内容&#xff1a; 1、 基本理解 2、 深入理解具体实现 3、 实际用例 一、基本理解和使用 一般来说&#xff0c;常用的数据结构分为线性数据结构和非线性数据结构&#xff0c…

dx逆向建模步骤_使用Creaform HandySCAN扫描建筑异形曲面并进行正逆向建模

问题说明当在一个已有的物体上需要精确构建一个新的结构&#xff0c;而已有的物体并没有三维模型&#xff0c;我们需要对已有的物体进行三维扫描和逆向建模&#xff0c;然后再在逆向模型的基础上进行在设计&#xff0c;将新的结构融合进去。这个过程中&#xff0c;如果已有的物…

让并发和容错更容易:Akka示例教程

翻译&#xff1a;自由的柠檬 原文链接&#xff1a;http://www.toptal.com/scala/concurrency-and-fault-tolerance-made-easy-an-intro-to-akka 挑战 写并发程序很难。程序员不得不处理线程、锁和竞态条件等等&#xff0c;这个过程很容易出错&#xff0c;而且会导致程序代码难…

java特性基本研究

文章目录前言一、java是什么&#xff1f;二、特性简介1、简单性2、面向对象3、健壮性4、安全性5、可移植性6、多线程7、动态性三、补充说明java1、java程序的运行过程2、java虚拟机简介3、其他4、java应用领域前言 最近在系统的学习java&#xff0c;简单总结一些java和其他语言…

java文件过滤器的使用

前言&#xff1a; java.io.FileFilter&#xff08;过滤器接口&#xff09;boolean accept(File pathname)File类提供了如下方法使用过滤器&#xff1a;public File[] listFiles(FileFilter filter) 代码如下&#xff1a; //过滤器类 class filter1 implements FileFilter{Overr…

树的简单理解

文章目录简介树存储结构的实现二叉树基本定义性质二叉树的树实现二叉树的遍历简介 树是一种树是一种非线性数据结构&#xff0c;所谓非线性数据结构&#xff0c;是指可以元素之间的关系可以一对多或多对一&#xff0c;多对多的数据结构。树是一种典型的非线性数据结构&#xf…

yapi 插件_当Swagger遇上YApi,瞬间高大上了!

Swagger经常被人吐槽界面不够好看、功能不够强大&#xff0c;其实有很多工具可以和Swagger结合使用&#xff0c;结合之后就会变得非常好用。之前写过一篇文章《Swagger界面丑、功能弱怎么破&#xff1f;用Postman增强下就给力了&#xff01;》&#xff0c;有朋友留言说YApi也很…

为什么HashMap初始大小为16,为什么加载因子大小为0.75,这两个值的选取有什么特点?...

先看HashMap的定义&#xff1a; public class HashMap<K,V>extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable HashMap是AbstractMap的子类&#xff0c;实现了Map接口。 HashMap() Constructs an empty HashMap with the default initi…