闭包的几大应用场景js

1.返回值: 以闭包的形式将函数中的变量返回

    // 1.返回值
    //这个很好理解就是以闭包的形式将 name 返回。
    function fn() {
      var name = "hello";
      return function () {
        return name;
      }
    }
    var fnc = fn();
    console.log(fnc());//hello

2.函数赋值

在闭包里面给fn2函数设置值,闭包的形式把name属性记忆下来,执行会输出 hello。

    //2.函数赋值
    var fn2;
    function fn() {
      var name = "hello";
      //将函数赋值给fn2
      fn2 = function () {
        return name;
      }
    }
    fn()//先执行在进行赋值
    console.log(fn2());//执行输出fn2
    //在闭包里面给fn2函数设置值,闭包的形式把name属性记忆下来,执行会输出 hello。

3.函数参数

    //用闭包返回一个函数,把此函数作为另一个函数的参数,在另一个函数里面执行这个函数,最终输出 hello
    function fn() {
      var name = "hello";
      return function callbabck() {
        return name;
      }
    }
    var fn1 = fn()//执行函数将函数返回,然后赋值给fn1
    function fn2(f) {
      //将函数作为参数传入
      console.log(f());//执行函数并输出
    }

4.IIFE自执行函数

    (function () {
      var name = "hello";
      var fn1 = function () {
        return name;
      }
      //直接在自执行函数里面调用fn2,将fn1作为参数传入
      fn2(fn1);
    })()
    function fn2(f) {
      //将函数作为参数传入
      console.log(f());//执行函数并输出
    }

5.循环赋值

    //每秒执行一次
    for (let i = 1; i <= 10; i++) {
      (function (j) {
        //j来接收
        setTimeout(function () {
          console.log(j);//1,2,3,4,5,6,7,8,9,10
        }, j * 1000);//为什么
      })(i)
    }

setTimeout是每一个setTimeout都会从第一秒开始计时,所以是每秒打印。

6.getter和setter

    /**
     * 第一次输出 hello 用setter以后再输出 world
     * ,这样做可以封装成公共方法,防止不想暴露的属性和函数暴露在外部。
    */
    function myfun() {
      var name = "hello";
      setName = function (n) {
        name = n;
      }
      getName = function (n) {
        return name;
      }
      //将setName和getName作为对象的属性返回
      return {
        setName: setName,
        getName: getName,
      }
    }
    var myfn1 = myfun();//返回对象,属性setName和getName是两个函数
    console.log(myfn1.getName());//getter
    myfn1.setName("林雨诗");//setter修改闭包里面的name
    console.log(myfn1.getName());

7.迭代器(执行一次函数往下取值)

    var arr = ["aa", "bb", 'cc'];
    function increament(arr) {
      var i = 0;
      return function () {
        //这个函数每次被执行都返回数组arr中 i下标对应的元素
        return arr[i++] || "数组值已经遍历完";
      }
    }
    var res = increament(arr);
    console.log(res());//aa
    console.log(res());//bb
    console.log(res());//cc
    console.log(res());//数组值已经遍历完

8.首次区分(相同的参数,函数不会重复执行)

    var func1 = (function () {
      var arr = [];//用来缓存的数组
      return function (val) {
        if (arr.indexOf(val) == -1) {//缓存中没有则表示需要执行
          arr.push(val);//将参数push到缓存数组中
          console.log("函数被执行了", arr);
          //这里写想要执行的函数
        } else {
          console.log("函数已经被执行过,此次函数不需要执行");
        }
        console.log("函数调用完调用一下,方便查看已缓存的数组:", arr);
      }
    })();
    func1(10);
    func1(10);
    func1(1000);
    func1(200);
    func1(1000);
    //可以明显的看到首次执行的会被存起来,再次执行直接取。

9.缓存

    //比如求和操作,如果没有缓存,每次调用都要重复计算
    //,采用缓存已经执行过的去查找,查找到了就直接返回,不需要重新计算。
    //
    var syxfunc = (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;
      }
    })()
    syxfunc(1, 2, 3, 4, 5);
    syxfunc(1, 2, 3, 4, 5);
    syxfunc(1, 2, 3, 4, 5, 6);
    syxfunc(1, 2, 3, 4, 5, 8);
    syxfunc(1, 2, 3, 4, 5, 6);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值