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 相关文章推荐
node.js中的fs.truncate方法使用说明
Dec 15 Javascript
jQuery mobile 移动web(4)
Dec 20 Javascript
有关jquery与DOM节点操作方法和属性记录
Apr 15 Javascript
微信小程序之picker日期和时间选择器
Feb 09 Javascript
jQuery+ajax实现局部刷新的两种方法
Jun 08 jQuery
cordova入门基础教程及使用中遇到的一些问题总结
Nov 14 Javascript
javascript高仿热血传奇游戏实现代码
Feb 22 Javascript
浅谈js获取ModelAndView值的问题
Mar 28 Javascript
在mpvue框架中使用Vant WeappUI组件库的注意事项【推进】
Jun 09 Javascript
layui复选框限制选择个数的方法
Sep 18 Javascript
vue页面跳转实现页面缓存操作
Jul 22 Javascript
js实现删除json中指定的元素
Sep 22 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
PHP 增加了对 .ZIP 文件的读取功能
2006/10/09 PHP
php 文件上传类代码
2011/08/06 PHP
PHP实现下载远程图片保存到本地的方法
2017/06/19 PHP
实例分析10个PHP常见安全问题
2019/07/09 PHP
雄兵连第三季海报曝光,艾妮熙德成主角,蔷薇新造型
2021/03/09 国漫
js跨浏览器实现将字符串转化为xml对象的方法
2013/09/25 Javascript
js实现键盘Enter键提交表单的方法
2015/05/27 Javascript
jQuery在线选座位插件seat-charts特效代码分享
2015/08/27 Javascript
利用jQuery及AJAX技术定时更新GridView的某一列数据
2015/12/04 Javascript
JS实现字符串转日期并比较大小实例分析
2015/12/09 Javascript
详解jQuery的Cookie插件
2016/11/23 Javascript
总结js中的一些兼容性易错的问题
2017/12/18 Javascript
详解vue-router 命名路由和命名视图
2018/06/01 Javascript
vue集成kindeditor富文本的实现示例代码
2019/06/07 Javascript
vue history 模式打包部署在域名的二级目录的配置指南
2019/07/02 Javascript
微信小程序如何播放腾讯视频的实现
2019/09/20 Javascript
Vue 实现一个命令式弹窗组件功能
2019/09/25 Javascript
JS箭头函数和常规函数之间的区别实例分析【 5 个区别】
2020/05/27 Javascript
[41:17]完美世界DOTA2联赛PWL S3 access vs CPG 第二场 12.13
2020/12/17 DOTA
django 发送手机验证码的示例代码
2018/04/25 Python
Python清空文件并替换内容的实例
2018/10/22 Python
Python从函数参数类型引出元组实例分析
2019/05/28 Python
Python OpenCV实现鼠标画框效果
2020/08/19 Python
python关于调用函数外的变量实例
2019/12/26 Python
Pytest测试框架基本使用方法详解
2020/11/25 Python
CSS3中的opacity属性使用教程
2015/08/19 HTML / CSS
初中女生自我鉴定
2013/12/19 职场文书
高一生物教学反思
2014/01/17 职场文书
宿舍保安职务说明书
2014/02/25 职场文书
2014年信息技术工作总结
2014/12/16 职场文书
长江三峡导游词
2015/01/31 职场文书
乐山大佛导游词
2015/02/02 职场文书
2015年小学开学寄语
2015/02/27 职场文书
淮海战役观后感
2015/06/11 职场文书
2015初中政治教学工作总结
2015/07/21 职场文书
MySQL 表空间碎片的概念及相关问题解决
2021/05/07 MySQL