js闭包的9个使用场景


Posted in Javascript onDecember 29, 2020

1.返回值(最常用)

//1.返回值 最常用的
    function fn(){
        var name="hello";
        return function(){
            return name;
        }
    }
    var fnc = fn();
    console.log(fnc())//hello

这个很好理解就是以闭包的形式将 name 返回。

2.函数赋值

var fn2;
function fn(){
    var name="hello";
    //将函数赋值给fn2
    fn2 = function(){
        return name;
    }
}
fn()//要先执行进行赋值,
console.log(fn2())//执行输出fn2

在闭包里面给fn2函数设置值,闭包的形式把name属性记忆下来,执行会输出 hello。

3.函数参数

function fn(){
    var name="hello";
    return function callback(){
        return name;
    }
}
var fn1 = fn()//执行函数将返回值(callback函数)赋值给fn1,
 
function fn2(f){
    //将函数作为参数传入
    console.log(f());//执行函数,并输出
}
fn2(fn1)//执行输出fn2

用闭包返回一个函数,把此函数作为另一个函数的参数,在另一个函数里面执行这个函数,最终输出 hello

4.IIFE(自执行函数)

(function(){
        var name="hello";
        var fn1= function(){
            return name;
        }
        //直接在自执行函数里面调用fn2,将fn1作为参数传入
        fn2(fn1);
    })()
    function fn2(f){
        //将函数作为参数传入
        console.log(f());//执行函数,并输出
    }

直接在自执行函数里面将封装的函数fn1传给fn2,作为参数调用同样可以获得结果 hello

5.循环赋值

//每秒执行1次,分别输出1-10
for(var i=1;i<=10;i++){
    (function(j){
        //j来接收
        setTimeout(function(){
            console.log(j);
        },j*1000);
    })(i)//i作为实参传入
}

如果不采用闭包的话,会有不一样的情况,可以看我自己 闭包 的文章。

6.getter和setter

function fn(){
        var name='hello'
        setName=function(n){
            name = n;
        }
        getName=function(){
            return name;
        }
         
        //将setName,getName作为对象的属性返回
        return {
            setName:setName,
            getName:getName
        }
    }
    var fn1 = fn();//返回对象,属性setName和getName是两个函数
    console.log(fn1.getName());//getter
        fn1.setName('world');//setter修改闭包里面的name
    console.log(fn1.getName());//getter

第一次输出 hello 用setter以后再输出 world ,这样做可以封装成公共方法,防止不想暴露的属性和函数暴露在外部。

7.迭代器(执行一次函数往下取一个值)

var arr =['aa','bb','cc'];
function incre(arr){
    var i=0;
    return function(){
        //这个函数每次被执行都返回数组arr中 i下标对应的元素
         return arr[i++] || '数组值已经遍历完';
    }
}
var next = incre(arr);
console.log(next());//aa
console.log(next());//bb
console.log(next());//cc
console.log(next());//数组值已经遍历完

8.首次区分(相同的参数,函数不会重复执行)

var fn = (function(){
               var arr=[];//用来缓存的数组
                   return function(val){
                       if(arr.indexOf(val)==-1){//缓存中没有则表示需要执行
                           arr.push(val);//将参数push到缓存数组中
                           console.log('函数被执行了',arr);
                           //这里写想要执行的函数
                       }else{
                           console.log('此次函数不需要执行');
                       }
                       console.log('函数调用完打印一下,方便查看已缓存的数组:',arr);
                   }
               })();
        
       fn(10);
       fn(10);
       fn(1000);
       fn(200);
       fn(1000);

执行结果如下:

js闭包的9个使用场景

可以明显的看到首次执行的会被存起来,再次执行直接取。

9.缓存

//比如求和操作,如果没有缓存,每次调用都要重复计算,采用缓存已经执行过的去查找,查找到了就直接返回,不需要重新计算
      
     var fn=(function(){
        var cache={};//缓存对象
        var calc=function(arr){//计算函数
            var sum=0;
            //求和
            for(var i=0;i<arr.length;i++){
                sum+=arr[i];
            }
            return sum;
        }
         
        return function(){
            var args = Array.prototype.slice.call(arguments,0);//arguments转换成数组
            var key=args.join(",");//将args用逗号连接成字符串
            var result , tSum = cache[key];
            if(tSum){//如果缓存有   
                console.log('从缓存中取:',cache)//打印方便查看
                result = tSum;
            }else{
                //重新计算,并存入缓存同时赋值给result
                result = cache[key]=calc(args);
                console.log('存入缓存:',cache)//打印方便查看
            }
            return result;
        }
     })();
    fn(1,2,3,4,5);
    fn(1,2,3,4,5);
    fn(1,2,3,4,5,6);
    fn(1,2,3,4,5,8);
    fn(1,2,3,4,5,6);

输出结果:

js闭包的9个使用场景

以上就是js闭包的9个使用场景的详细内容,更多关于js 闭包使用场景的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
Javascript的IE和Firefox兼容性汇编(zz)
Feb 02 Javascript
jQuery 渐变下拉菜单
Dec 15 Javascript
Javascript学习笔记7 原型链的原理
Jan 11 Javascript
基于jquery的拖动布局插件
Nov 25 Javascript
微信浏览器内置JavaScript对象WeixinJSBridge使用实例
May 25 Javascript
jQuery插件ImageDrawer.js实现动态绘制图片动画(附源码下载)
Feb 25 Javascript
JS版微信6.0分享接口用法分析
Oct 13 Javascript
Bootstrap modal 多弹窗之叠加引起的滚动条遮罩阴影问题
Feb 27 Javascript
全面介绍vue 全家桶和项目实例
Dec 27 Javascript
浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
Dec 20 Javascript
Vue实现类似Spring官网图片滑动效果方法
Mar 01 Javascript
详解关于webpack多入口热加载很慢的原因
Apr 24 Javascript
JavaScript 防盗链的原理以及破解方法
Dec 29 #Javascript
vue3+typeScript穿梭框的实现示例
Dec 29 #Vue.js
Vue.extend 登录注册模态框的实现
Dec 29 #Vue.js
vue实现简易的双向数据绑定
Dec 29 #Vue.js
elementui实现预览图片组件二次封装
Dec 29 #Javascript
利用node.js开发cli的完整步骤
Dec 29 #Javascript
微信小程序实现可拖动悬浮图标(包括按钮角标的实现)
Dec 29 #Javascript
You might like
如何使用Linux的Crontab定时执行PHP脚本的方法
2011/12/19 PHP
CodeIgniter生成网站sitemap地图的方法
2013/11/13 PHP
php生成xml时添加CDATA标签的方法
2014/10/17 PHP
PHP生成条形码大揭秘
2015/09/24 PHP
Smarty高级应用之缓存操作技巧分析
2016/05/14 PHP
创建无限极分类树型结构的简单方法
2017/06/20 PHP
PHP递归统计系统中代码行数
2019/09/19 PHP
关于laravel 数据库迁移中integer类型是无法指定长度的问题
2019/10/09 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
2020/02/23 PHP
给moz-firefox下添加IE方法和属性
2007/04/10 Javascript
解析John Resig Simple JavaScript Inheritance代码
2012/12/03 Javascript
解读JavaScript中 For, While与递归的用法
2013/05/07 Javascript
Javascript实现单张图片浏览
2014/12/18 Javascript
JavaScript判断一个字符串是否包含指定子字符串的方法
2015/03/18 Javascript
jQuery原生的动画效果
2015/07/10 Javascript
谈谈jQuery Ajax用法详解
2015/11/27 Javascript
不使用JavaScript实现菜单的打开和关闭效果demo
2018/05/01 Javascript
Python写的Tkinter程序屏幕居中方法
2015/03/10 Python
Python中取整的几种方法小结
2017/01/06 Python
Django 2.0版本的新特性抢先看!
2018/01/05 Python
Python网络编程基于多线程实现多用户全双工聊天功能示例
2018/04/10 Python
python监控进程脚本
2018/04/12 Python
python实现内存监控系统
2021/03/07 Python
解决pycharm下os.system执行命令返回有中文乱码的问题
2019/07/07 Python
python解析命令行参数的三种方法详解
2019/11/29 Python
Python Pillow.Image 图像保存和参数选择方式
2020/01/09 Python
基于Python的自媒体小助手---登录页面的实现代码
2020/06/29 Python
利用html5的websocket实现websocket聊天室
2013/12/12 HTML / CSS
小学教师培训感言
2014/02/11 职场文书
公司请假条格式
2014/04/11 职场文书
实习公司领导推荐函
2014/05/21 职场文书
单身申明具结书
2015/02/26 职场文书
生日寿星公答谢词
2015/09/29 职场文书
行政后勤人员工作计划应该怎么写?
2019/08/16 职场文书
python实现web邮箱扫描的示例(附源码)
2021/03/30 Python
《总之就是很可爱》新作短篇动画《总之就是很可爱~制服~》将于2022年夏天播出
2022/04/07 日漫