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日

相关文章

  • vue router 源码概览案例分析

    题目中提到的“vue router 源码概览案例分析”可以分成以下三个关键点进行讲解: Vue Router 是什么以及为什么要使用它? Vue Router 的源码结构是怎样的? 通过案例分析 Vue Router 源码中的核心功能是如何实现的? 我们将依次对这三个关键点进行阐述。 1. Vue Router 是什么以及为什么要使用它? Vue Route…

    JavaScript 2023年6月11日
    00
  • 浅谈JavaScript中this的指向问题

    浅谈JavaScript中this的指向问题 在javascript中,this关键字的指向问题一直是比较困惑的一个问题,因为它的指向受到一定的影响。如果我们没有完全搞清楚this的指向规则,那么在使用this的时候可能会带来很多不方便和错误的情况。接下来让我们一起来浅谈一下javascript中this的指向问题。 this的指向规则 在javascrip…

    JavaScript 2023年6月10日
    00
  • JS定义类的六种方式详解

    JS定义类的六种方式详解 JavaScript 是一门面向对象的编程语言,定义类是面向对象编程中非常重要的部分。在JavaScript中,定义类的方式有六种。 方式一:函数定义类 使用函数定义类是最常见的方式之一。 function Person(name, age) { this.name = name; this.age = age; } Person.…

    JavaScript 2023年5月27日
    00
  • 基于JavaScript实现文件共享型网站

    下面将详细讲解“基于JavaScript实现文件共享型网站”的完整攻略。 前置条件 熟悉HTML、CSS和JavaScript基本知识; 熟悉Node.js开发环境和相关模块。 操作步骤 1. 创建文件夹 首先在本地文件夹中创建一个新的文件夹,命名为“file-sharing-website”。 2. 初始化项目 打开终端,进入到该文件夹中,执行以下命令: …

    JavaScript 2023年5月27日
    00
  • JavaScript原型与原型链深入探究使用方法

    JavaScript原型与原型链深入探究使用方法 原型 JavaScript中每个函数都有一个prototype属性,它指向一个对象。这个对象就是所谓的“原型对象”或“原型”。我们可以在原型对象上添加方法和属性,这些方法和属性可以被构造函数创建的实例所共享。在原型对象上定义的方法和属性,可以被该构造函数所创建的所有实例共享使用。这样,我们就可以省略实例中相同…

    JavaScript 2023年6月10日
    00
  • 关于vue 结合原生js 解决echarts resize问题

    关于vue结合原生js解决echarts resize问题,可以使用下面的攻略: 攻略说明 采用vue-echarts插件加载echarts,并且绑定图表的 DOM 元素到 vue 实例中 使用 js 的 resize() 方法,监听 window 大小变化,当窗口大小发生改变时,使用 triggerResize() 方法通知echarts自适应大小 示例说…

    JavaScript 2023年6月11日
    00
  • javascript跑马灯抽奖实例讲解

    下面我将详细讲解“JavaScript跑马灯抽奖实例讲解”的完整攻略,包括示例说明: 1. 介绍 在网页中,常常需要用到一些动态效果来吸引用户,其中跑马灯和抽奖都是常见的实现方式。在本文中,我们将学习如何使用JavaScript实现跑马灯抽奖效果。 2. 实现原理 跑马灯抽奖是根据随机数来获取中奖结果的,而文字的滚动效果则是通过定时器来实现的。下面是实现跑马…

    JavaScript 2023年6月11日
    00
  • vue、react等单页面项目部署到服务器的方法及vue和react的区别

    一、将单页面应用(SPA)部署到服务器的方法 将SPA打包生成静态文件使用webpack等打包工具将SPA打包生成静态文件,一般会生成一个dist文件夹,里面包含了SPA的所有静态资源文件。 部署到服务器将生成的静态文件复制到服务器上的部署目录,如/var/www/html,然后通过nginx等Web服务器进行访问即可。 示例:假设我们已经将一个Vue单页面…

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