iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >学习JavaScript中的闭包closure应该注意什么
  • 676
分享到

学习JavaScript中的闭包closure应该注意什么

2024-04-02 19:04:59 676人浏览 八月长安
摘要

目录闭包简述1.闭包使得内部函数可以访问外部函数的属性(变量或方法)2.闭包的广阔应用场景3.用闭包模拟私有方法4.从性能角度考虑,非必要不使用闭包闭包简述 Mozilla 上这样解

闭包简述

Mozilla 上这样解释闭包:一个函数和对其周围状态(lexical environment,词法环境) 的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。 也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 javascript 中, 每当创建一个函数, 闭包就会在函数创建的同时被创建出来。 词法(lexical)一词指的是,词法作用域根据源代码中声明变量的位置来确定该变量在何处可用。

我对闭包的理解:闭包使得可以模拟私有项,可以使得内部函数可以访问外部函数的属性,非必要不用闭包。

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

这有时会带来便利, 例如有时可以通过在外部函数声明变量,代替全局变量。 下面是一个设备视口大小改变时,重置 echarts 的例子。

// 设备视口大小改变时,重置 echarts
let timer = null
window.onresize = function () {
  // 简单的防抖动处理
  if (timer) clearTimeout(timer)
  timer = setTimeout(() => {
    console.log(timer)
    chart.resize()
  }, 500)
}

也可以考虑使用闭包的方式,而不必在声明全局变量(更大范围的变量) timer,例如这样

window.onresize = this.debounce(() => {
  chart.resize()
}, 500)

function debounce (fn, delay = 500) {
  let timer = null
  return (p) => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn(p)
    }, delay)
  }
}

2.闭包的广阔应用场景

闭包的广阔应用场景,体现在你使用只有一个方法的对象的地方,都可以使用闭包。

因为闭包允许将函数与其所操作的某些数据(环境)关联起来。这显然类似于面向对象编程。 在面向对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。

而在日常开发中,符合使用闭包的场景其实很常见,因为使用只有一个方法的对象的地方,都可以使用闭包, 而使用也并不太麻烦,加上闭包本身就是 javascript 的重要知识点,这些加起来使得闭包具备了实用的特征。

但如果你不熟练闭包,有更好的替代方案,也不必非要使用,因为实用好用的东西很多, 闭包只是选择之一,为了给自己多一种选择闭包又是要学的。

3.用闭包模拟私有方法

JavaScript 没有类似 JAVA 那样的将方法声明为私有的原生支持,但我们可以使用闭包来模拟私有方法。 私有方法不仅仅有利于限制对代码的访问,还提供了管理全局命名空间的强大能力, 避免非核心的方法弄乱代码的公共接口部分。

下面的示例展现了如何使用闭包来定义公共函数,并令其可以访问私有函数和变量。这个方式也称为模块模式(module pattern)

window.onload = () => {
  let Counter1 = makeCounter(); // 创建实例1
  let Counter2 = makeCounter(); // 创建实例2

  console.log(Counter1.value()); // value:0
  Counter1.add(); // 调用增加函数,执行加一
  console.log(Counter1.value()); // value:1

  console.log(Counter2.value()); // value:0

  // 注意,实例2的 value 没有受到实例1的影响,也就是说 Counter1 和 Counter2 各自独立。
  // 每次调用其中一个计数器时,通过改变这个变量的值,会改变这个闭包的词法环境。
  // 然而在一个闭包内对变量的修改,不会影响到另外一个闭包中的变量。

  // undefined,Counter1 无法直接访问私有项 privateNumber
  console.log(Counter1.privateNumber);
  // Counter1.changeBy is not a function,Counter1 无法直接访问私有项 changeBy
  console.log(Counter1.changeBy(10));

  // 问私有项无法被访问,这提示我们应关注到以这种方式使用闭包,
  // 提供了许多与面向对象编程相关的好处 —— 特别是数据隐藏和封装。
}

/// 声明一个模块:计数器,模块内部包含了两个模拟的私有项 privateNumber 和 changeBy,
// 并返回一个对象,对象内部包含三个属性,分别是 add(),reduce(),value()。
let makeCounter = function () {
  let privateNumber = 0;

  function changeBy (val) {
    privateNumber += val;
  }

  return {
    add: function () {
      changeBy(1);
    },
    reduce: function () {
      changeBy(-1);
    },
    value: function () {
      return privateNumber;
    }
  }
};

在这个例子中,包含两个私有项: 名为 privateCounter 的变量和名为 changeBy 的函数。 这两项都无法在函数外部直接访问。必须通过匿名函数返回的三个公共函数访问。这就是模拟了私有特性。

4.从性能角度考虑,非必要不使用闭包

关于闭包的性能,我无深入的理解,也无数据证明,但我认为这挺重要的。

因此,这里引用一下 Mozilla 的说法:

如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的, 因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响。

例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。 原因是这将导致每次构造器被调用时,方法都会被重新赋值一次(也就是说,对于每个对象的创建,方法都会被重新赋值)。

英文原文:

It is unwise to unnecessarily create functions within other functions if closures are not needed for a particular task, as it will negatively affect script perfORMance both in terms of processing speed and memory consumption.

For instance, when creating a new object/class, methods should normally be associated to the object's prototype rather than defined into the object constructor. The reason is that whenever the constructor is called, the methods would get reassigned (that is, for every object creation).

概括就是一句话,非必要不用闭包。好东西很多闭包只是之一, 当然闭包作为js的重要知识点,作为可能的解决方案之一,学习是必要的。

到此这篇关于学习JavaScript中的闭包closure应该注意什么的文章就介绍到这了,更多相关JS 闭包closuret内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 学习JavaScript中的闭包closure应该注意什么

本文链接: https://www.lsjlt.com/news/150700.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 学习JavaScript中的闭包closure应该注意什么
    目录闭包简述1.闭包使得内部函数可以访问外部函数的属性(变量或方法)2.闭包的广阔应用场景3.用闭包模拟私有方法4.从性能角度考虑,非必要不使用闭包闭包简述 Mozilla 上这样解...
    99+
    2022-11-13
  • 让我们一起来学习一下什么是javascript的闭包
    目录一、常见的闭包二、实例详解总结什么是闭包: 闭包是一个存在内部函数的引用关系。 该引用指向的是外部函数的局部变量对象(前提是内部函数使用了外部函数的局部变量) 闭包的作用: 延长...
    99+
    2022-11-13
  • Python中闭包和自由变量的使用方法与注意事项是什么
    这篇文章主要为大家展示了“Python中闭包和自由变量的使用方法与注意事项是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Python中闭包和自由变量的使用方法与注意事项是什么”这篇文章吧。...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作