js闭包的9个使用场景

一个函数的作用域可以访问另一个函数的局部变量,这个变量所在的函数就是闭包函数。

闭包使得内部函数可以访问外部函数的属性(变量或方法)

 

1.返回值

function fn(){
    let  name="123";
       return function(){
            return name;
        }
}
let fnc=fn();
console.log(fnc()); //123   
//以闭包的行事将name变量返回;
或者:console.log(fn()()); //123
2.函数赋值
var fn2;
function fn(){
    var  name="123";
    fn2=function(){
        retun name;
    }
}

fn();//先执行函数进行赋值
console.log(fn2());//123
3.函数参数(有点类似回调)
function fn(){
    var name="123";
    return function callback(){
        return name;
    }
}

let fn1=fn();//执行函数将返回值(callback函数)赋值给fn1

function fn2(f){
    //将函数作为参数传入
    console.log(f());//执行函数,并输出
}

fn2(fn1);  //123 
等价于:fn2(fn()); //123  因为fn1=fn(); 
用闭包返回一个函数,把函数作为另一个函数的参数,在另一个函数里面执行这个函数,最终输出123;
4.IIFE(自执行函数)

(function(){
    var name="123";
    let fn1=function(){
        return name;
    }
    //直接在自执行函数里面调用fn2,将fn1作为参数传入
    fn2(fn1);
})()

function fn2(f){
    //将函数作为参数传入
    console.log(f());//执行函数,并输出
}
//直接在自执行函数里面将封装的函数fn1传给fn2,作为参数调用者可以获得结果123

5.循环赋值
//每执行1次,分别输出1-10
for(let i=0;i<=10;i++){
    (function(j){
        //j是形参 接收
        setTimeout(function(){
            console.log(j);
        },1000*j)
    })(i)//i作为实参传入
}
6.getter和setter
function fn(){
    var name="123";
    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
7.迭代器(执行一次函数往下去取下一个值)
var arr=[1,2,3]
function incre(arr){
    let i=0;
    return function(){
        //这个函数每次被执行都返回数组arr中i下标对应的元素
        rerurn arr[i++] || '完成'
    }
}
var next=incre(arr);
console.log(next());//1
console.log(next());//2
console.log(next());//3
console.log(next());//完成
8.首次区分(相同的参数,函数不会重复执行)
var fn=(function(){
    var arr=[]l
    return function(val){
        if(arr.indexOf(val)==1){
            arr.push(val);
            consle.log('函数执行完了')
            //这里写想要执行的函数
        }else{
            console.log('此次函数不需要执行');    
        }
        console.log('函数调用完打印一次',arr);
    }    

})();
fn(10);
fn(10);
fn(1000);
fn(100);
fn(1000);
9.缓存
//比如求和操作,如果没有缓存,每次调用都要重复计算,采用缓存已经执行过的去查找,查找到了就直接返回,不需重新计算
var fn=(function(){
    var cache={};
    var calc=function(arr){
        var sum=0;
        //求和
        for(let i==0;i<arr.length;i++){
            sum+=arr[i];
        }
        return sum;
    }
    return function(){
        var args=Array.prototype.slice.call(arguments,0);
        var key=args.join(".");
        var result,tSum=cache[key];
        if(Sum){
            console.log('从缓存中取:',cache);
            result=tSum;
        }else{
            result=cache[key]=calc(args);
            console.log('存入缓存:',cache);
        }
        return result;
    }
})();
fn(1,2,3)
fn(1,2,3,4,5)

回调函数也是闭包

function fn(zy,fn){
    console.log(`完成${zy}作业。`);
    var isFinished=true;
    let timer=setTimeout(()=>{
        if(isFinished){
            console.log("看完电视了");
            fn("看完电视了");
        }else{
            console.log("作业没完成,还在继续写作业");
            fn("作业没完成,还在继续写作业");
        }
    },2000);//2秒回调
}

//需求 做完数学作业,妈妈允许我看电视
fn("数学",function(res){
    console.log(res);
})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值