javaScript-闭包与作用域

Posted 火腿肠烧烤大赛冠军

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javaScript-闭包与作用域相关的知识,希望对你有一定的参考价值。

环境与作用域

  1. 全局环境不会被回收
  2. 任何位置都可以访问全局环境

函数的作用域和环境

  1. 函数执行后会每一次都会创建一块新的作用域
  2. 父级函数可以访问子函数作用域

延伸函数环境生命周期

只要有人在用,环境就不会被清空,所以可以采用复制的方式

    function sam() {
      let n = 1;
      return function sum(){
        console.log(++n);
      };
      // sum();
    };
    let sss = sam();;
    sss();
    sss();
    sss();
    sss();
    sss();

构造函数中的作用域的使用形态

只要函数还在和他同级作用域的内容就会保留

var有函数作用域,可以通过函数模拟块级作用域

    for (var i = 1; i <= 3; i++) {
      (function(i) {
        setTimeout(function() {
          console.log(i);
        }, 1000);
      })(i);
    }

什么是闭包及与其他语言对比实例

子函数可以访问到其他函数作用域当中的数据

应用

  1. 利用闭包获取区间值
  let lessons = [
    {
      title: "sss",
      click: 589,
      price: 36
    },
    {
      title: "aaa",
      click: 445,
      price: 20
    },
    {
      title: "ddd",
      click: 129,
      price: 67
    },
    {
      title: "vvv",
      click: 293,
      price: 300
    }
  ];
  function getPrice(a, b) {
    return function (param) {
      return param.price >= a && param.price <= b
    }
  }
  console.table(lessons.filter(getPrice(10, 100)));
  1. 动画举例

    如果left放在eventlistener中会每次都生成一个新的left导致反复抖动,所以要把left放到父级作用域 加深理解:每一个函数生成都会创建一个新的作用域并且和他一个作用域的值也不会改变

  <style>
    button {
      position: absolute;
    }
  </style>
  <button message="后盾人">houdunren</button>

  let btns = document.querySelectorAll("button");
  btns.forEach(function (item) {
    //parent
    let left = 1;
    item.addEventListener("click", function () {
      setInterval(function () {
        item.style.left = left++ + "px";
      }, 100);
    });
  });
  1. 排序函数
  let lessons = [
    {
      title: "媒体查询响应式布局",
      click: 89,
      price: 12
    },
    {
      title: "FLEX 弹性盒模型",
      click: 45,
      price: 120
    },
    {
      title: "GRID 栅格系统",
      click: 19,
      price: 67
    },
    {
      title: "盒子模型详解",
      click: 29,
      price: 300
    }
  ];
  function order(field, type = "asc") {
    return function (a, b) {
      if (type == "asc") return a[field] > b[field] ? 1 : -1;
      return a[field] > b[field] ? -1 : 1;
    };
  }
  let hd = lessons.sort(order("price"));
  console.table(hd);

闭包带来的内存泄漏

  <div desc="hello">开源产品</div>


  let divs = document.querySelectorAll("div");
  divs.forEach(function (item) {
    let desc = item.getAttribute("desc");
    item.addEventListener("click", function () {
      // console.log(item.getAttribute("desc"));
      console.log(desc);
      console.log(item);
    });
    item = null; //解决方式
  });

闭包与this

this的指向为当前函数调用的对象;
所以闭包函数中直接用this无法使用当前作用域中的值;
解决方式:箭头函数,指向当前函数上下文;

    let hd = {
      user: "ssss",
      get: function() {
        // console.log(this);
        // let This = this;
        return () => {
          return this.user;
        };
      }
    };
    let a = hd.get();
    console.log(a());

以上是关于javaScript-闭包与作用域的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript闭包

JS你不知道的JavaScript 笔记—— 作用域与闭包 - 编译原理 - LHS - RHS - 循环与闭包 - 模块 - 词法作用域 - 动态作用域

JavaScript闭包

javscript闭包的准备工作 -- 作用域与作用域链

JavaScript之作用域与闭包详解

你不知道的JavaScript1(作用域与闭包)