js闭包所用的场合以及优缺点分析

JS闭包是指函数可以访问当前环境外的变量,并在执行后保留对这些变量的引用。通俗的说,就是函数内部的函数可以访问函数外部函数的变量。下面我们来一步一步详细讲解JS闭包所用的场合以及优缺点分析。

什么是闭包

在JS中,每当创建一个函数,该函数就会创建一个作用域(scope)链。作用域链可以帮助函数在查找变量时,逐级向上进行查找,直到找到为止。而闭包,正是通过这个作用域链来实现对父级作用域中变量的访问。

闭包的用处

封装变量

JS闭包可以避免全局变量带来的命名冲突,可以将一个变量封装在一个函数内部,从而防止其他函数修改该变量。如下所示:

function createCounter() {
  var count = 0;
  return function () {
    count++;
    console.log(count);
  }
}

var counter = createCounter();
counter(); // 输出1
counter(); // 输出2
counter(); // 输出3

在上述代码中,我们首先定义了一个外部函数createCounter,并在其中定义了一个局部变量count。随后我们又定义了一个内部函数,并在内部函数中修改了count变量的值。最后将内部函数作为函数createCounter的返回值返回。

我们可以发现,在createCounter函数执行完之后,count变量并没有从内存中销毁,而是在内部函数中得以访问。这就是闭包的内存保留机制。

实现函数或对象私有化

闭包能够让我们实现一些私有方法的效果,因为闭包可以使得函数内部的变量在函数执行完毕后仍然存活在内存中,不会被垃圾回收站收回。这就可以用来实现JS中的对象私有化。如下所示:

function Point(x, y) {
  this.x = x;
  this.y = y;
  var self = this;
  var length = 0; //私有变量
  // 计算点到原点的距离
  var calcLength = function () {
    length = Math.sqrt(self.x * self.x + self.y * self.y);
  }
  calcLength();

  this.getLength = function () {
    return length;
  }
}

var point = new Point(3, 4);
console.log(point.getLength()); // 输出 5
console.log(point.length); // 输出 undefined

我们在Point函数中定义了一个私有变量length,用于保存点到原点的距离。在函数中还定义了一个私有函数calcLength用于计算长度。由于length被定义在Point函数的内部,所以我们不能直接访问到length变量。但是在Point函数中又定义了一个公有方法getLength,该方法能够返回length的值。

通过上述代码,我们可以看到,point对象虽然不能直接访问到length,但是却能够通过调用getLength方法来获取到length的值。

闭包的缺点

尽管闭包可以为我们提供很多便利,但是它也有一些缺点。

使用闭包需要注意内存泄漏问题。当函数执行完毕,内部变量仍然被占用,不会被回收,这就造成了内存泄漏。为了避免内存泄漏,我们需要注意不要在闭包中存储过多的外部变量。

闭包中的作用域链访问虽说便利,但是它对性能也有一定的影响。因为作用域链的查找步骤需要多次访问内存,效率比较低下,因此过度使用闭包会导致页面性能下降,甚至造成浏览器的卡顿。

闭包的示例

示例1:封装变量

var counter = (function() {
    var count = 0;
    return function() {
        count++;
        console.log(count);
    };
})(); // 每次调用都会自增1

counter(); // 输出1
counter(); // 输出2
counter(); // 输出3

示例2:使用闭包实现节流函数

function throttle(fn, interval) {
  var startTime = 0;
  return function() {
    var endTime = new Date().getTime();
    if(endTime - startTime > interval) {
      fn.apply(this, arguments);
      startTime = endTime;
    }
  };
}

var func = function() {
  console.log('hello world');
};

var throtFunc = throttle(func, 1000);

throtFunc();
setTimeout(throtFunc, 500);
setTimeout(throtFunc, 900);
setTimeout(throtFunc, 1200);
setTimeout(throtFunc, 1600);

在上述示例中,我们定义了一个函数throttle,函数接收两个参数,第一个参数是要包装的函数,第二个参数表示间隔多少毫秒执行一次。throttle函数内部又返回了一个匿名函数,并在该匿名函数内部实现了函数节流的功能。最后,我们可以通过throttle函数来实现对其他函数的节流处理。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js闭包所用的场合以及优缺点分析 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • JS+Canvas实现满屏爱心和文字动画的制作

    接下来我将详细讲解“JS+Canvas实现满屏爱心和文字动画的制作”的完整攻略。 准备工作 创建 HTML 页面,并引入 Canvas 标签。 “`html Canvas Demo “` 在 JavaScript 文件中获取 Canvas 对象并设置宽高。 javascript var canvas = document.getElementById(“…

    JavaScript 2023年6月11日
    00
  • JavaScript作用域与作用域链优化方式

    我来介绍一下JavaScript作用域和作用域链的优化方式。 什么是JavaScript作用域 JavaScript作用域指的是变量和函数可访问的范围。在JavaScript中,作用域分为全局作用域和局部作用域。 全局作用域:指在代码的任何地方都可以访问的变量和函数,一般在页面的顶部定义。 var globalVar = "我是全局变量"…

    JavaScript 2023年6月11日
    00
  • JS中准确判断变量类型的方法

    当我们在编写JavaScript代码时,经常需要对不同的变量类型做出不同的操作。因此,准确判断变量类型是非常重要的一项技能。本文将分享几种JS中准确判断变量类型的方法,并提供两条示例进行演示。 使用typeof运算符判断变量类型 typeof运算符可以返回一个变量的数据类型,例如:字符串、数字、布尔值、对象、undefined和function六种。使用ty…

    JavaScript 2023年5月28日
    00
  • 解决微信内置浏览器返回上一页强制刷新问题方法

    解决微信内置浏览器返回上一页强制刷新问题方法 问题描述 在微信内置浏览器中,当用户点击返回上一页时,页面会被强制刷新,导致页面中的一些数据丢失或者重新加载,影响用户体验。 引起问题的原因 在微信内置浏览器中,当页面的url发生变化时,微信浏览器会强制刷新页面。这种情况下,页面中所有的数据都会被重新加载,导致我们在实现页面交互时的一些问题。 解决方案 方案一:…

    JavaScript 2023年6月11日
    00
  • JavaScript进阶之函数和对象知识点详解

    JavaScript进阶之函数和对象知识点详解 前言 JavaScript 是一门多范式的编程语言,而函数和对象是 JavaScript 语言的两个重要组成部分。了解 JavaScript 函数和对象的知识点是非常重要的,对 JavaScript 程序的编写和效率优化都有着重要的影响。 本篇文章将从概念、语法用法、应用等角度详细讲解 JavaScript 函…

    JavaScript 2023年5月18日
    00
  • javascript的惯性运动实现代码实例

    下面是“JavaScript的惯性运动实现代码实例”的完整攻略。 理解惯性运动 在开始编写代码实现惯性运动之前,我们需要先理解惯性运动的概念。 所谓惯性运动,指的是对象在受到外力作用后,由于惯性而产生的运动。比如说,当你用力向前推一个物体,它并不会立刻静止,而会先快速运动一段时间,然后逐渐减缓,最终停下来。 我们可以通过数学公式来描述物体的运动状态,其中包括…

    JavaScript 2023年6月11日
    00
  • javascript求日期差的方法

    当我们需要计算两个日期之间的差值时,可以使用JavaScript中内置的方法来帮助我们进行计算。下面是一些常用函数的示例说明。 方法1:使用getTime()方法求日期差 使用new Date()创建两个日期对象 通过调用getTime()方法获取两个日期对象的时间戳 用两个时间戳相减得到日期差 示例代码如下: let date1 = new Date(‘2…

    JavaScript 2023年5月27日
    00
  • javascript ajax类AJAXRequest2007-12-31 更新

    JavaScript AJAX类AJAXRequest2007-12-31是一种用于发送AJAX请求的JavaScript类。使用AJAXRequest类可以实现在不刷新页面的情况下,通过后台服务器获取数据并动态更新网页的应用。 下面是使用该类的详细攻略: 1. 引入AJAXRequest类 在使用AJAXRequest类之前,需要将类的代码引入到网页中。可…

    JavaScript 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部