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 相关文章推荐
Extjs学习笔记之一 初识Extjs之MessageBox
Jan 07 Javascript
ASP.NET中使用后端代码注册脚本 生成JQUERY-EASYUI的界面错位的解决方法
Jun 12 Javascript
JS.getTextContent(element,preformatted)使用介绍
Sep 21 Javascript
JavaScript动态创建div属性和样式示例代码
Oct 09 Javascript
适用于手机端的jQuery图片滑块动画
Dec 09 Javascript
你真的了解BOM中的history对象吗
Feb 13 Javascript
vue.js树形组件之删除双击增加分支实例代码
Feb 28 Javascript
简单实现js拖拽效果
Jul 25 Javascript
Vue项目webpack打包部署到Tomcat刷新报404错误问题的解决方案
May 15 Javascript
基于vue实现滚动条滚动到指定位置对应位置数字进行tween特效
Apr 18 Javascript
基于node+vue实现简单的WebSocket聊天功能
Feb 01 Javascript
9种方法优化jQuery代码详解
Feb 04 jQuery
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
Yii2搭建后台并实现rbac权限控制完整实例教程
2016/04/28 PHP
PHP利用超级全局变量$_POST来接收表单数据的实例
2016/11/05 PHP
PHP获取IP地址所在地信息的实例(使用纯真IP数据库qqwry.dat)
2016/11/15 PHP
javascript 表单规则集合对象
2009/07/21 Javascript
ExtJs使用总结(非常详细)
2012/03/22 Javascript
jQuery 借助插件Lavalamp实现导航条动态美化效果
2013/09/27 Javascript
document.forms[].submit()使用介绍
2014/02/19 Javascript
javascript判断chrome浏览器的方法
2014/03/26 Javascript
jQuery中attr()和prop()在修改checked属性时的区别
2014/07/18 Javascript
跟我学习javascript的call(),apply(),bind()与回调
2015/11/16 Javascript
跟我学习javascript的垃圾回收机制与内存管理
2015/11/23 Javascript
深入理解js中this的用法
2016/05/28 Javascript
jsp 网站引入外部css或者js失效问题解决
2016/10/31 Javascript
基于jQuery实现的幻灯图片切换
2016/12/02 Javascript
JavaScript如何获取到导航条中HTTP信息
2017/10/10 Javascript
JS面向对象的程序设计相关知识小结
2018/05/26 Javascript
JS加密插件CryptoJS实现的DES加密示例
2018/08/16 Javascript
JS如何获取地址栏的参数实例讲解
2018/10/06 Javascript
vue中keep-alive、activated的探讨和使用详解
2020/07/26 Javascript
解决antd Form 表单校验方法无响应的问题
2020/10/27 Javascript
Vue 事件的$event参数=事件的值案例
2021/01/29 Vue.js
Python转码问题的解决方法
2008/10/07 Python
如何在python字符串中输入纯粹的{}
2018/08/22 Python
通过python爬虫赚钱的方法
2019/01/29 Python
了解不常见但是实用的Python技巧
2019/05/23 Python
Pandas时间序列重采样(resample)方法中closed、label的作用详解
2019/12/10 Python
python实现超级玛丽游戏
2020/03/18 Python
HTML5本地存储之Web Storage应用介绍
2013/01/06 HTML / CSS
银行自荐信范文
2013/10/07 职场文书
2014学习优秀共产党员先进事迹思想汇报
2014/09/14 职场文书
群众路线自查自纠工作情况报告
2014/10/28 职场文书
2014年大班保育员工作总结
2014/12/02 职场文书
2015秋季开学演讲稿范文
2015/07/16 职场文书
婚前协议书怎么写,才具有法律效力呢 ?
2019/06/28 职场文书
解决Redis启动警告问题
2022/02/24 Redis
Nginx报404错误的详细解决方法
2022/07/23 Servers