javascript中闭包closure的深入讲解

yizhihongxing

JavaScript中闭包(closure)的深入讲解

在JavaScript中,闭包是一个非常重要的概念,也是面试中经常考察的知识点。下面将深入讲解JavaScript中闭包的概念、特点和使用方法。

什么是闭包

闭包指的是在一个函数内部使用另一个函数的变量,形成了一个作用域链,外部函数或其他地方无法访问这个内部函数的变量,但内部函数可以访问外层函数的变量。

举个例子:

function outer() {
  var a = 1;
  function inner() {
    console.log(a);
  }
  return inner;
}

var result = outer();
result(); // 输出 1

上面的示例中,我们定义了一个名为outer的函数,在outer函数内部定义了一个变量a和一个内部函数innerinner函数可以访问outer函数的变量a并输出。我们将outer函数的返回值赋值给一个变量result,并执行该变量,最终输出结果为1。

在这个例子中,inner函数形成了一个闭包,因为它可以访问外层函数outer的变量a,并且我们通过将inner函数作为outer函数的返回值,保留了outer函数执行时的上下文环境,使得inner函数一直存在并可以调用。

闭包的特点

  • 内部函数可以访问外部函数的变量和参数。
  • 外部函数无法访问内部函数的变量和参数。
  • 内部函数形成了一个闭包,可以持续的存在。

闭包的使用场景

1. 防抖和节流

防抖和节流是常见的优化性能的方式,可以用闭包来实现。

防抖

防抖指的是在一定时间内,多次触发同一事件,只执行最后一次,可以通过闭包保存定时器来实现。

function debounce(fn, delay) {
  var timer;
  return function() {
    var context = this,
        args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  }
}

上面的代码中,我们传入一个函数fn和一个时间delay,创建了一个闭包并返回一个新的函数,使用了setTimeout来设置定时器,保存了timer变量,clearTimeout用来清除上一次设置的定时器,防止重复执行。

节流

节流指的是在一定时间内,多次触发同一事件,只执行一次,可以通过闭包保存定时器和上次执行时间来实现。

function throttle(fn, delay) {
  var timer,
      lastTime;
  return function() {
    var context = this,
        args = arguments,
        nowTime = new Date().getTime();
    if (nowTime - lastTime > delay || !lastTime) {
      if (timer) {
        clearTimeout(timer);
        timer = null;
      }
      lastTime = nowTime;
      fn.apply(context, args);
    } else if (!timer) {
      timer = setTimeout(function() {
        fn.apply(context, args);
      }, delay);
    }
  }
}

上面的代码中,我们传入一个函数fn和一个时间delay,创建了一个闭包并返回一个新的函数,使用了setTimeout来设置定时器,保存了timer变量和上次执行时间lastTime,判断两次执行时间间隔是否大于delay,如果是则执行函数并更新lastTime,否则设置定时器等待。

2. 模块化开发

使用闭包可以实现类似于面向对象编程中的私有属性和方法,可以有效的避免全局变量污染。

var myModule = (function() {
  var privateVar = 0;
  function privateMethod() {
    console.log('private method');
  }
  return {
    publicVar: 1,
    publicMethod: function() {
      console.log('public method');
      privateMethod();
      privateVar++;
    }
  }
})();

上面的代码中,我们定义了一个名为myModule的变量,使用了闭包并返回了一个对象,包含了一个公共变量publicVar和一个公共方法publicMethod,同时也定义了一个私有变量privateVar和一个私有方法privateMethod,可以在公共方法中使用私有方法和变量。

总结

闭包是一个非常重要的概念,在JavaScript中使用闭包可以实现很多功能,如防抖和节流、模块化开发等。需要注意的是,由于闭包会占用内存,所以在使用时需要注意内存泄漏问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:javascript中闭包closure的深入讲解 - Python技术站

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

相关文章

  • 输入一个网址的时候,后台到底发生了一件件什么样的事

    当用户在浏览器中输入一个网址时,后台会经历如下过程: DNS解析 首先,浏览器需要将用户输入的网址转化为一个IP地址,这个过程称为DNS解析。浏览器将会向本地DNS服务器发出请求,本地DNS服务器可能会向上级DNS服务器继续发出请求,直到最终找到负责该域名的DNS服务器,并从中获取对应IP地址。如果本地DNS服务器中不存在对应域名的IP地址,将会继续向上级D…

    JavaScript 2023年6月10日
    00
  • JS遍历页面所有对象属性及实现方法

    JS遍历页面所有对象属性及实现方法 在JavaScript中,对象是一个非常重要的概念,通过对象可以将多种类型的数据(属性)和方法(函数)组合到一起,实现对数据的封装和操作。在前端开发中,遍历页面中所有的对象属性是非常常见的需求,本文将介绍如何实现这一功能。 1. for…in循环 for…in循环是JavaScript中遍历对象属性的一种基本方法,…

    JavaScript 2023年5月27日
    00
  • 12 款 JS 代码测试必备工具(翻译)

    首先,这篇文章主要介绍了12款JS代码测试必备工具,包括Jest、Mocha、Chai、Sinon、Enzyme、Cypress、Protractor、Karma、Nightwatch.js、Puppeteer、TestCafe和Codeceptjs。这些工具可以帮助开发者提高代码质量和测试效率。 以下是这些工具的详细介绍: Jest:Jest是一个建立在J…

    JavaScript 2023年5月27日
    00
  • Ajax高级笔记 JavaScript高级程序设计笔记

    《Ajax高级笔记》和《JavaScript高级程序设计笔记》是两本非常优秀的前端技术书籍,适合有一定编程基础的人群进行阅读。下面是对这两本书的攻略说明。 Ajax高级笔记攻略 了解Ajax Ajax (Asynchronous JavaScript + XML),意思是利用JavaScript在不刷新页面的前提下与服务器端进行数据交互,实现前后端数据的异步…

    JavaScript 2023年5月18日
    00
  • javascript 易错知识点实例小结

    JavaScript 易错知识点实例小结 在编写 JavaScript 代码的过程中,会遇到一些易错的知识点,可能会导致出现预期外的结果,甚至是程序的崩溃。因此,我们需要了解这些易错知识点,并采取正确的措施避免这些问题的发生。在本文中,我们将详细讲解 JavaScript 易错知识点,并提供实例来帮助读者更好地理解。 目录 变量提升 this 关键字 闭包 …

    JavaScript 2023年6月10日
    00
  • js的Object.assign用法示例分析

    简介 Object.assign 是 ES6 新增的一个API,能够将一个或多个源对象的属性复制到目标对象上。它的参数依次为目标对象和一个或多个源对象。如果源对象中的属性已经存在在目标对象中,那么源对象中的属性值将覆盖目标对象中的属性值。 语法 Object.assign(target, …sources) 参数: target (必须):要将源对象复制…

    JavaScript 2023年5月27日
    00
  • javascript 二维数组的实现与应用

    JavaScript 二维数组的实现与应用 什么是二维数组? 二维数组指的是数组中包含数组的数据结构。在JavaScript中,我们可以通过创建一个包含其他数组的数组来创建一个二维数组。 如何实现一个二维数组? 在Javascript中,我们可以使用以下方法来声明并初始化一个二维数组: let myArray = [ [1, 2, 3], [4, 5, 6]…

    JavaScript 2023年5月27日
    00
  • javascript基础知识讲解

    JavaScript基础知识讲解 JavaScript是一种广泛使用的编程语言,可用于前端开发、后端开发和移动应用程序开发等领域。在本篇文章中,我们将重点讨论JavaScript的基础知识,包括变量、数据类型、运算符、流程控制语句和函数等内容。 变量 在JavaScript中,使用var、let或const声明变量。其中,var和let都可以用于声明全局和局…

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