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 Base类 包含基本的方法
Jul 22 Javascript
基于jquery的模态div层弹出效果
Aug 21 Javascript
Extjs EditorGridPanel中ComboBox列的显示问题
Jul 04 Javascript
解决3.01版的jquery.form.js中文乱码问题的解决方法
Mar 08 Javascript
通过Javascript创建一个选择文件的对话框代码
Jun 16 Javascript
原生js和jQuery写的网页选项卡特效对比
Apr 27 Javascript
纯js实现无限空间大小的本地存储
Jun 18 Javascript
jQuery实现列表内容的动态载入特效
Aug 08 Javascript
详解AngularJS 模态对话框
Apr 07 Javascript
详解如何在vue中使用sass
Jun 21 Javascript
详解node.js 事件循环
Jul 22 Javascript
JavaScript实现筛选数组
Mar 02 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
预告映像公开!第1章续篇剧场版动画《Princess Principal Crown Handler》4月10日上映!
2020/03/06 日漫
php使用session二维数组实例
2014/11/06 PHP
页面利用渐进式JPEG来提升用户体验度
2014/12/01 PHP
php简单实现单态设计模式的方法分析
2017/07/28 PHP
tp5.1 框架数据库高级查询技巧实例总结
2020/05/25 PHP
统一接口:为FireFox添加IE的方法和属性的js代码
2007/03/25 Javascript
js 面向对象的技术创建高级 Web 应用程序
2010/02/25 Javascript
JavaScript中对象属性的添加和删除示例
2014/05/12 Javascript
JavaScript AOP编程实例
2015/06/16 Javascript
使用CSS+JavaScript或纯js实现半透明遮罩效果的实例分享
2016/05/09 Javascript
微信公众平台开发教程(六)获取个性二维码的实例
2016/12/02 Javascript
基于MVC方式实现三级联动(JavaScript)
2017/01/23 Javascript
vue使用watch 观察路由变化,重新获取内容
2017/03/08 Javascript
利用jQuery解析获取JSON数据
2017/04/08 jQuery
jQuery实现web页面樱花坠落的特效
2017/06/01 jQuery
微信小程序 动画的简单实例
2017/10/12 Javascript
小程序实现多选框功能
2018/10/30 Javascript
layui输入框只允许输入中文且判断长度的例子
2019/09/18 Javascript
详解为什么Vue中的v-if和v-for不建议一起用
2021/01/13 Vue.js
python二分法实现实例
2013/11/21 Python
Django应用程序中如何发送电子邮件详解
2017/02/04 Python
python3大文件解压和基本操作
2017/12/15 Python
Django网络框架之创建虚拟开发环境操作示例
2019/06/06 Python
使用keras框架cnn+ctc_loss识别不定长字符图片操作
2020/06/29 Python
Web前端绘制0.5像素的几种方法
2017/08/11 HTML / CSS
法国时尚童装网站:Melijoe
2016/08/10 全球购物
大学生军训感想
2014/02/16 职场文书
考核工作实施方案
2014/03/30 职场文书
委托书格式
2014/08/01 职场文书
企业优秀团员事迹材料
2014/08/20 职场文书
党员志愿者活动方案
2014/08/28 职场文书
法务专员岗位职责
2015/02/14 职场文书
给女朋友的道歉短信
2015/05/12 职场文书
2016年猴年新春致辞
2015/08/01 职场文书
Redis性能监控的实现
2021/07/09 Redis
Oracle 触发器trigger使用案例
2022/02/24 Oracle