JavaScript闭包详解

yizhihongxing

JavaScript闭包详解

什么是闭包

闭包是指在一个函数内部定义的函数可以访问该函数的上下文环境中的变量和函数,即使在函数外部访问该函数的上下文环境也是无法访问到的。

举个例子:

function outer() {
  var name = "张三";
  function inner() {
    console.log(name); // 可以访问外部函数中定义的变量
  }
  return inner;
}

var innerFun = outer();
innerFun(); // "张三"

在这个例子中,函数inner()嵌套在另一个函数outer()内部,它可以访问outer()函数中定义的变量name。在outer()函数中,返回内层函数inner()的引用,这就形成了一个闭包。

闭包的应用场景

闭包的应用有很多,其中最常见的是在封装对象的时候,使对象的部分属性或方法对外部不可访问。

封装变量

在JavaScript中,没有真正的私有变量。但是,如果我们定义一个函数并立即执行它,那么内部变量就会被封装,并且只能通过返回的函数才能访问到它们。这种方法被称为模块模式。

示例代码如下:

var obj = (function() {
  var name = "张三";
  var age = 18;
  function getName() {
    return name;
  }
  function getAge() {
    return age;
  }
  return {
    getName: getName,
    getAge: getAge
  }
})();

console.log(obj.getName()); // "张三"
console.log(obj.getAge()); // 18

在这个例子中,我们定义了一个立即执行的匿名函数,并返回一个包含getName()getAge()方法的对象。这些方法内部访问了闭包中的name和age变量,但是从外部无法访问。

记忆化函数

记忆化是一个非常有用的技巧,可以根据函数的输入缓存运算结果,以避免重复计算。下面是一个例子,计算斐波那契数列中的第n项。

function fibonacci(n) {
  if (n === 1 || n === 2) {
    return 1;
  }
  return fibonacci(n - 1) + fibonacci(n - 2);
}

如果我们计算fibonacci(40),那么这个函数就会被调用1346269次,导致程序非常慢。考虑使用记忆化技巧。

function fibonacci(n) {
  var cache = {};
  function inner(num) {
    if (num === 1 || num === 2) {
      return 1;
    }
    if (cache[num]) {
      return cache[num]; // 从缓存中返回结果
    }
    var result = inner(num - 1) + inner(num - 2);
    cache[num] = result; // 缓存结果
    return result;
  }
  return inner(n);
}

在这个例子中,我们定义了一个内部函数inner(),它访问了一个闭包中的变量cache。cache保存了已经计算过的结果,如果我们已经计算过结果,那么直接从cache中返回结果即可。这个问题的计算复杂度被降低到了O(n),且即使是计算较大的斐波那契数列,也能非常快速地完成。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript闭包详解 - Python技术站

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

相关文章

  • vue3.0+vant3.0快速搭建项目的实现

    下面就是“vue3.0+vant3.0快速搭建项目的实现”的完整攻略: 简介 在新版Vue和Vant的配合下,搭建高质量的移动端Web应用变得更加容易和快捷。接下来,我们将向您介绍如何使用Vue3.0和Vant3.0快速搭建项目。 准备工作 在开始之前,您需要确保您的电脑上已经安装了Node.js和Vue CLI。由于本攻略假设您已经对Vue CLI和Van…

    JavaScript 2023年6月11日
    00
  • JavaScript如何删除对象的某个属性详析

    让我来详细讲解一下“JavaScript如何删除对象的某个属性”。 1. 删除对象属性的方法 JavaScript提供了两种方法来删除对象的某个属性: 1.1 delete操作符 delete操作符可以删除对象的属性,语法如下: delete object.property; 其中,object是待删除属性的对象,property是待删除的属性名。例如: v…

    JavaScript 2023年6月10日
    00
  • js中substring和substr的详细介绍与用法

    JS中substring和substr的详细介绍与用法 概述 JavaScript中的substring()和substr()函数均可用于截取一个字符串的一部分,但它们的使用方式略有不同。 substring() substring()函数用于截取字符串的一部分,并返回一个新的字符串。它接受两个参数,第一个参数是起始位置,第二个参数是结束位置(不含)。如果没…

    JavaScript 2023年5月28日
    00
  • AngularJS通过$location获取及改变当前页面的URL

    AngularJS是一个前端MVVM框架,通过它可以方便地进行网页开发。在网页开发中,经常需要获取或改变当前页面的URL,AngularJS提供了$location服务实现这一功能。下面是一份简要的攻略: 1. $location服务的概述 AngularJS中的$location服务用于获取和改变URL。通过$location服务,可以获取当前页面的URL…

    JavaScript 2023年6月11日
    00
  • JavaScript图片的Base64编码以及转换详解

    JavaScript图片的Base64编码以及转换详解 在进行前端开发时,我们会遇到需要将图片转换为Base64编码的情况,本篇攻略将会详细讲解JavaScript如何进行图片的Base64编码以及如何进行Base64编码的还原。 图片的Base64编码 在JavaScript中,可以使用FileReader的方法将图片读取为base64格式的字符串,具体步…

    JavaScript 2023年5月19日
    00
  • JQuery 动态扩展对象之另类视角

    JQuery 动态扩展对象之另类视角 在 Javascript 中,对象是一种灵活的数据类型,可以随意添加、删除、修改属性。JQuery 作为一个基于 Javascript 的库,提供了很多方便的方法和 API,其中一个非常常用的功能就是动态扩展对象。这篇文章将介绍 JQuery 中动态扩展对象的另一种视角,希望对初学者来说有所帮助。 对象的动态扩展 在 J…

    JavaScript 2023年6月10日
    00
  • JS实现图片预加载无需等待

    为了使页面加载更快,我们可以在页面载入之前就预先加载所需要的图片资源。这个过程称为“图片预加载”。当用户访问页面时,这些图片就已经在本地缓存中了,从而不会出现因等待加载而导致页面卡顿的情况。下面是JS实现图片预加载无需等待的完整攻略。 1. 获取图片的URL列表 首先,我们需要获取要预加载的图片列表。这个列表可以是一个数组,也可以通过DOM元素获取。下面是一…

    JavaScript 2023年6月11日
    00
  • JavaScript Object的extend是一个常用的功能

    JavaScript中的extend功能常用于对象的继承、对象属性的扩展等场景。本篇攻略将详细讲解如何使用JavaScript Object的extend功能。 什么是JavaScript对象的extend JavaScript中的Object对象是所有对象的父对象,每个对象都有Object的属性和方法。其中extend方法就是Object对象中常用的一个方…

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