ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

前端日常一问:为何要使用闭包?请说一下闭包的原理和使用场景

2021-08-23 17:02:19  阅读:132  来源: 互联网

标签:闭包 function 函数 作用域 一问 使用 变量 name


闭包的由来

说的闭包,首先就要知道作用域和作用域链。

作用域
作用域是一个变量和函数的作用范围。
分为全局作用域和局部作用域,在ES6之前,是没有块级作用域概念的,只有函数作用域。
函数作用域都是相对独立的,外部是访问不到函数作用域中的变量的。
比如

function fn1() {
	var name = 'nini';
}
console.log(name)

此时,我们在外部是访问不到fn1中的name变量的。

作用域链
作用域链其实就是一个对象列表或者对象链。
在javascript中,每个函数都有自己的执行上下文环境。当我们要查找一个变量时,首先会从当前作用域开始查找,如果当前查找不到就到父级作用域查找,直至找到该变量。如果作用域顶端(作用域顶端是全局变量)也查找不到的话,会抛出异常ReferenceError(ReferenceError同作用域判别失败有关)。

何为闭包

闭包,通俗的来说,就是在当前作用域能访问到外部作用域中的对象。
就像在上述中,要在外部访问到fn1中的name,就可以使用闭包来实现。

function fn1() {
	var name = 'nini';
	function getName() {
		console.log(name)
	}
	return getName
}
var getName = fn1()
getName()

MDN中对闭包的定义是:

闭包是指可以访问到自由变量的函数

那什么是自由变量呢?其实就是指既不是当前函数的参数也不是当前函数的内部变量的变量。
其实这是理论上的闭包,实践上的闭包要满足以下两点:

  1. 即使创建它的上下文已经销毁,它仍然存在;
  2. 代码中引用了自由变量;

闭包的原理

实际上是利用了函数作用域链的特性。
如果函数内部定义的函数引入了外部函数的活动对象,就会把它添加到函数的作用域链中,函数执行完毕,其执行作用域链销毁,但因内部函数的作用域链仍然在引用这个活动对象,所以其活动对象不会被销毁,直到内部函数被烧毁后才被销毁。

使用闭包的好处

  • 可作为私有成员存在
  • 可使变量长期保持在内存中
  • 避免全局污染

闭包的缺点

javascript中如果对象不再被引用,那么这些对象将会被JS引擎的垃圾回收器回收;反之,这些对象一直会保存在内存中。

  • 对内存消耗有负面影响。因内部函数保存了对外部变量的引用,导致无法被垃圾回收,增大内存使用量
  • 使用不当会导致内存泄漏

闭包的应用场景

拿到正确的值(模仿块级作用域)

for(var i = 0; i < 6; i++) {
    (function(j){
        setTimeout(() => {
            console.log(j);
        }, j * 1000);
    })(i)
}

设置私有变量

let name = Symbol();
class Private {
	constructor(s) {
		this[name] = s
	}
	foo() {
		console.log(this[name])
	}
}

函数防抖

function debounce(fn, wait=50) {
	let timer;
	return function(...arguments) {
		if(timer){
			clearTimeout(timer);
		}
		timer = setTimeout(()=>{
			fn.apply(this, arguments);
		}, wait)
	}
}

参考

JavaScript深入之闭包
从作用域链谈闭包
闭包实际应用场景

标签:闭包,function,函数,作用域,一问,使用,变量,name
来源: https://www.cnblogs.com/mmsxs/p/15176663.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有