温故而知新之- Javascript闭包

举报
余人杰 发表于 2020/09/27 15:40:14 2020/09/27
【摘要】 讲到闭包,可能有些人会慌,其实闭包很常用,慌是因为对知识点掌握不牢,下面我们来复习一下闭包。

什么是闭包呢?闭包是函数的一种特性,是指子函数可以访问外部作用域变量

闭包这个特性,在处理事件绑定,异步请求时起到非常重要的作用。


按照上面描述的特性,可以理解Javascript中所有的函数都是闭包。


前面我们复习过作用域,其实它就已经使用过这个闭包特性了,回顾下:

function info() {
  let name = '余人杰';
  return function () {
  	return name; // 使用了外部作用域的变量name
  }
}
let hwName = info();
console.log(hwName ()); //余人杰


其实在很多应用场景中,我们都会使用到闭包特性,让我们再来巩固下知识:

例如下面这个 返回数组区间元素的小需求:

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
function between(num1, num2) {
  return function(n) {
    return n >= num1 && n <= num2;
  };
}
console.log(arr.filter(between(2, 6))); //  [2, 3, 4, 5, 6]


使用闭包来指定按照某个字段排序数组:

let fruits = [
  {
    name: "apple",
    favorite: 9,
    price: 20
  },
  {
    name: "pear",
    favorite: 5,
    price: 50
  },
  {
    name: "watermelon",
    favorite: 45,
    price: 30
  },
  {
    name: "banana",
    favorite: 35,
    price: 20
  }
];
function order(k) {
  return (a, b) => (a[k] > b[k] ? 1 : -1);
}
console.table(fruits.sort(order("favorite")));


当然,我们也许认识下使用闭包会有哪些问题。

闭包特性中上级作用域会为函数保存数据,从而造成内存泄漏问题,如下代码所示:

<body>
  <a desc="fruits">水果</a>
  <a desc="drink">饮料</a>
</body>
<script>
  let aList = document.querySelectorAll("a");
  aList.forEach(function(item) {
    item.addEventListener("click", function() {
      console.log(item.getAttribute("desc"));
    });
  });
</script>


怎么处理这种问题呢?我们可以通过清除不需要的数据来解决解决内存泄漏问题

let aList = document.querySelectorAll("a");
aList.forEach(function(item) {
  let desc = item.getAttribute("desc");
  item.addEventListener("click", function() {
    console.log(desc);
  });
  item = null;
});


心得:闭包这个基础知识,在面试中出场率很高,不用慌,认真掌握牢这个基础知识点,难不倒你的,加油。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。