理解js闭包9大使用场景
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);
执行结果如下:

可以明显的看到首次执行的会被存起来,再次执行直接取。
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);
输出结果:

转载于:https://blog.csdn.net/dkm123456/article/details/111644638
理解js闭包9大使用场景的更多相关文章
- javascript深入理解js闭包(转)
javascript深入理解js闭包 转载 2010-07-03 作者: 我要评论 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...
- 理解JS闭包
从事web开发工作,尤其主要是做服务器端开发的,难免会对客户端语言JavaScript一些概念有些似懂非懂的,甚至仅停留在实现功能的层面上,接下来的文章,是记录我对JavaScript的一些概念的理解 ...
- 理解JS闭包的几个小实验
学了JavaScript有一段时间了,但是对闭包还是不太理解,于是怀着心中的疑问做了几个小实验,终于有点明白了. 首先看一下MDN上的定义:闭包是函数和声明该函数的词法环境的组合. 简单来说,闭包是一 ...
- javascript深入理解js闭包(个人理解,大神勿喷)
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- javascript深入理解js闭包
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- 深入理解JS闭包
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- javascript深入理解js闭包[转]
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- (转)javascript深入理解js闭包
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- javascript深入理解js闭包(看了挺多的,感觉这篇比较透彻)
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...
随机推荐
- Spark-3-调优要点
1 内存调整要点 Memory Tuning,Java对象会占用原始数据2~5倍甚至更多的空间.最好的检测对象内存消耗的办法就是创建RDD,然后放到cache里面去,然后在UI上面看storage的变 ...
- BUUCTF 刮开有奖 WriteUp
题目链接 https://buuoj.cn/challenges#%E5%88%AE%E5%BC%80%E6%9C%89%E5%A5%96 题解 用IDA打开,按F5反编译,双击进入DialogFun ...
- 容器编排系统k8s之Ingress资源
前文我们了解了k8s上的service资源的相关话题,回顾请参考:https://www.cnblogs.com/qiuhom-1874/p/14161950.html:今天我们来了解下k8s上的In ...
- django获取choices的显示值
1,models.py #订单表 class Orders(models.Model): status_cat = ( ('0', '待装货'), ('1', '正在运输'), ('2', '已到达目 ...
- 用python写图片格式批量处理工具
一.思路分析 其实,照片处理要求很简单,主要是两个方面:一个是调整图片尺寸(即宽x高),另一个是调整图片的大小(即压缩).为了实现这两个功能,利用python中的PIL库即可,其安装方法如下: pip ...
- 纯Python绘制艺术感满满的山脊地图,创意满分
1 简介 下面的这幅图是英国摇滚乐队 Joy Division 在1979年发行的其第一张录音室专辑 Unknown Pleasures 的封面,由艺术家 Peter Saville 基于射电脉冲星信 ...
- Core3.0中Swagger使用JWT
前言 学习ASP.NETCore,原链接 https://www.cnblogs.com/laozhang-is-phi/p/9511869.html 原教程是Core2.2,后期也升级到了Core3 ...
- 使用IDE练习插件【廖雪峰】
使用廖雪峰大神的插件,安装过程中,一直出现问题,然后在他的Java教程下面看大家的评论也有点晕了(很多人说的是jar包,结果其实是下的依旧是zip包) 最终解决方法: 将zip包解压到同名文件夹中,再 ...
- idea 【Maven Projects # Profiles】问题记录
今天启动接一个新项目,然后项目启动后发现启动的环境和预想的不一致,查看 pom 文件确认自己是 dev 无误之后,但是启动的就是 test 环境. 问题 发现了启动环境不对不对之后,自己试了一种解决办 ...
- PP模块的组织架构
组织架构的层次,从上而下依次是: (1),集团-->对应系统client级别,用户登录SAP系统时,每一个client就是对应一个集团:在数据库中,每一个client都对应一个唯一的标识. (2 ...