面试题:讲讲你对闭包的理解?有什么优缺点

2024-06-04 16:04

本文主要是介绍面试题:讲讲你对闭包的理解?有什么优缺点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

面试题:讲讲你对闭包的理解?有什么优缺点?

对闭包的理解

从 JS 作用域链的角度出发,函数外部无法访问到函数中的变量,但函数内部可以访问到其外部的变量。所谓闭包(closure),是一种在函数外部访问函数内部变量的一种方式。通常通过在函数中返回一个新函数的方式实现闭包,这个新函数中可以访问到返回它的函数中的所有执行上下文。

词法作用域:创建闭包时所在的作用域

对于以下示例,A 函数返回了 B 函数,此时 B 函数中可以访问到 A 函数中的所有执行上下文(变量等),将返回的 B 函数赋给一个变量,此时在 A 函数外也可以访问到 A 函数中定义的变量(包括为了得到 B 函数传给 A 函数的参数)。

function A(n){function B(){n++;console.log(`n=${n}`)}return B;
}let x = A(0);
x(); // n=1
x(); // n=1

通过以上示例,我们也可以认为闭包就是能读取其他函数内部变量的函数

闭包的优缺点

优点

  1. 数据封装:闭包可以将数据封装起来,并通过特定接口向外暴露

    function createCounter() {let count = 0; // 封装数据return { // 通过返回的闭包对封装数据进行访问和修改increment: function() {count++;return count;},decrement: function() {count--;return count;},getCount: function() {return count;}};
    }const counter = createCounter();
    console.log(counter.increment()); // 1
    console.log(counter.increment()); // 2
    console.log(counter.getCount()); // 2
    console.log(counter.decrement()); // 1
    
  2. 减少全局变量:闭包可以减少程序中对全局变量的依赖,从而避免命名冲突和全局命名空间的污染

  3. 函数工厂:闭包可以用来创建函数工厂,根据传入的参数,动态生成不同的函数。

    function powerFactory(exp) {return function(base) {return Math.pow(base, exp);};
    }const square = powerFactory(2); // 传入指数为 2,则生成平方函数
    const cube = powerFactory(3); // 传入指数 3,则生成立方函数console.log(square(4)); // 输出 16
    console.log(cube(2)); // 输出 8
    
  4. 惰性计算(一种缓存实现):闭包可以用于惰性计算,即在有需要的时候才计算值,从而提高性能。这也可以理解为缓存的一种实现方式,某些值在第一次访问时计算并缓存,之后访问时直接返回缓存的值。

    function lazyValue(fn) {let cachedValue;return function() {if (cachedValue === undefined) {cachedValue = fn();}return cachedValue;};
    }const getValue = lazyValue(() => {console.log("Computing value...");return 42;
    });console.log(getValue()); // "Computing value..." 42
    console.log(getValue()); // 42
    

缺点

  1. 内存泄漏:闭包会导致被其引用的变量无法被垃圾回收,此时这些内存无法被其他程序所利用,从而易造成内存泄漏。解决方式-1 为:在不需要使用闭包时,手动清理闭包引用(即将指向闭包的变量赋值为 null)。解决方式-2 为使用闭包而不创建闭包

    function createClosure() {var largeArray = new Array(1000000).fill('data');return function() {console.log(largeArray[0]);};
    }var closure = createClosure(); // 由于 largeArray 被闭包引用,所以无法被垃圾回收
    closure = null; // 解除对闭包的引用,允许垃圾回收器回收 largeArraycreateClosure(); // 使用闭包,而不创建闭包
    
  2. 性能问题:因为闭包会持有其词法作用域中的变量,从而会导致这些变量的生命周期变长,从时间的角度来说占用了更多内存。此外,闭包的原理是基于作用域链查找,使用闭包时,JS 引擎需要在多层作用域链中查找变量,从而影响执行效率。每次创建闭包时,都会涉及到内存分配操作。频繁创建和销毁闭包会增加垃圾回收的频率和开销,影响程序整体性能。解决方式:尽量重用闭包,减少闭包的创建次数,减少不必要的作用域嵌套。

  3. 代码复杂性:闭包的使用会增加代码的复杂性,使得代码可读性下降,从而可维护性降低。

REFERENCES

https://www.runoob.com/w3cnote/closure-intro.html

这篇关于面试题:讲讲你对闭包的理解?有什么优缺点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1030483

相关文章

一文带你理解Python中import机制与importlib的妙用

《一文带你理解Python中import机制与importlib的妙用》在Python编程的世界里,import语句是开发者最常用的工具之一,它就像一把钥匙,打开了通往各种功能和库的大门,下面就跟随小... 目录一、python import机制概述1.1 import语句的基本用法1.2 模块缓存机制1.

深入理解C语言的void*

《深入理解C语言的void*》本文主要介绍了C语言的void*,包括它的任意性、编译器对void*的类型检查以及需要显式类型转换的规则,具有一定的参考价值,感兴趣的可以了解一下... 目录一、void* 的类型任意性二、编译器对 void* 的类型检查三、需要显式类型转换占用的字节四、总结一、void* 的

深入理解Redis大key的危害及解决方案

《深入理解Redis大key的危害及解决方案》本文主要介绍了深入理解Redis大key的危害及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、背景二、什么是大key三、大key评价标准四、大key 产生的原因与场景五、大key影响与危

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

荣耀嵌入式面试题及参考答案

在项目中是否有使用过实时操作系统? 在我参与的项目中,有使用过实时操作系统。实时操作系统(RTOS)在对时间要求严格的应用场景中具有重要作用。我曾参与的一个工业自动化控制项目就采用了实时操作系统。在这个项目中,需要对多个传感器的数据进行实时采集和处理,并根据采集到的数据及时控制执行机构的动作。实时操作系统能够提供确定性的响应时间,确保关键任务在规定的时间内完成。 使用实时操作系统的

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

如何通俗理解注意力机制?

1、注意力机制(Attention Mechanism)是机器学习和深度学习中一种模拟人类注意力的方法,用于提高模型在处理大量信息时的效率和效果。通俗地理解,它就像是在一堆信息中找到最重要的部分,把注意力集中在这些关键点上,从而更好地完成任务。以下是几个简单的比喻来帮助理解注意力机制: 2、寻找重点:想象一下,你在阅读一篇文章的时候,有些段落特别重要,你会特别注意这些段落,反复阅读,而对其他部分