ICode9

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

闭包

2020-08-28 16:02:07  阅读:236  来源: 互联网

标签:闭包 displayName name var makeFunc 函数


闭包

定义

闭包是指有权访问另外一个函数作用域中的变量的函数。——《JavaScript高级程序设计》

函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包closure)。——MDN

例子

举个栗子:

function makeFunc() {
    var name = "Mozilla";
    function displayName() {
        alert(name);
    }
    return displayName;
}

var myFunc = makeFunc();
myFunc();

上述代码是MDN中的样例代码,在makeFunc函数内部定义了一个displayName的函数,并将其作为返回值。在displayName中,其执行的功能是弹窗显示makeFunc中的定义的变量name。抛开代码细节,从上述代码实现的功能也就是将name输出。

你可能觉得上述写法过于冗长,多此一举,你可能会写出如下更加精简的代码。

function makeFunc() {
    var name = "Mozilla";
  	alert(name);
}

makeFunc();

但是,现在增加了一个需求,在显示完name之后,在name名称后面添加一个!号。

如果沿用刚才改写过的代码的话,你需要改写成如下代码:

var name = "Mozilla";

function makeFunc() {
  	alert(name);
  	name += '!';
}

makeFunc();
makeFunc();

因为如果不将var name移到makeFunc外部的话,当你调用makeFunc结束后,函数内部变量将被垃圾回收机制回收,无法实现添加!的功能。但是这样带来的坏处是污染全局的名称空间且全局中的任意函数都能调用到name,而且如果我想对于另外一个name做同样的操作,则需要创建新的变量名加以区分。

如果我们使用最开始的代码的话,我们只需要改写成如下形式:

function makeFunc() {
	var name = "Mozilla";
	function displayName() {
		console.log(name);
		name += '!';
	}
	return displayName;
}

var myFunc = makeFunc();
myFunc();
myFunc();

可以理解为我们将name作为了makeFunc()的私有变量,var myFunc = makeFunc(); 创建了一个词法环境,这个词法环境不会在第一次调用后销毁。displayNamedisplayName所处的词法环境就构成了一个闭包.

闭包产生的条件

从上面的例子中我们大致能了解到闭包产生的条件:

  1. 存在函数嵌套;
  2. 嵌套的内部函数必须引用在外部函数中定义的变量;
  3. 嵌套的内部函数必须被执行。

闭包的作用

同时我们也能了解到闭包的作用:

  1. 变量常驻内存,对于实现某些业务很有帮助,比如计数器之类的。

  2. 架起了一座桥梁,让函数外部访问函数内部变量成为可能。

  3. 私有化,一定程序上解决命名冲突问题,可以实现私有变量

但是缺点是变量一直存在于内存中,无法被释放,可能随着这些碎片的累计会造成内存溢出。

释放内存

那么如何释放内存呢?

以上述例子为例,令myFunc=null 即可。

参考

  1. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

  2. https://juejin.im/post/6858052418862235656#heading-13

标签:闭包,displayName,name,var,makeFunc,函数
来源: https://www.cnblogs.com/njuclc/p/13577975.html

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

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

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

ICode9版权所有