首页 > 其他分享 >JS闭包理解

JS闭包理解

时间:2023-05-02 18:00:12浏览次数:39  
标签:闭包 function console 函数 count JS 理解 return

概念

在一个函数中嵌套另一个函数,嵌套(内部)函数对其容器(外部)函数是私有的。闭包是一个可以自己拥有独立的环境与变量的表达式(通常是函数,因为ES6有块级作用域的概念)

闭包是指有权访问另一个函数作用域中变量的函数。

闭包作用:

  • 可以在函数外部访问到函数内部的局部变量;
  • 让这些变量始终保存在内存中,不会随着函数的结束而自动销毁;
// 案例
console.log('closure')
function add(){
  var count = 0;
  return function(){
    count += 1;
    return count;
  }
}
var a = add();
function fun(){
  alert(a());
}
fun();
fun();

// 定义了add()函数,函数内定义了count,返回值也是一个函数,内部函数引用外部函数变量count,因此形成闭包

闭包经典案例:要求点击每个li标签,弹出对应的索引。(0,1,2,3)

<ul>
  <li>i</li>
  <li>i</li>
  <li>i</li>
  <li>i</li>
</ul>
// 错误答案
for (var i = 0; i < elements.length; i++) {
  elements[i].onclick = function () {
    return (function (n) {
      console.log(n);
      alert(n);
    })(i);
  };
}
// 下面时这个题目的答案
// 每个li标签的onclick事件执行时,本身onclick绑定的function的作用域中没有变量i,i为undefined,则解析引擎会寻找父级作用域,
// 发现父级作用域中有i,且for循环绑定事件结束后,i已经赋值为4,所以每个li标签的onclick事件执行时,alert的都是父作用域中的i,也就是4。
// 这是作用域的问题。这里onclick事件绑定的函数形成闭包,但引用的变量i是全局的。闭包真正的含义是,如果一个函数访问了此函数的父级及父级以上的作用域变量,就可以称这个函数是一个闭包。
// 将for循环的var改为let就可以实现想要的效果
// 正确答案
for (let i = 0; i < elements.length; i++) {
  elements[i].onclick = function () {
    return (function (n) {
      console.log(n);
      alert(n);
    })(i);
  };
}

闭包造成内存泄漏问题

// 借助以下实例进行讲解
function fn () {
	let count = 1
	function fun () {
		count ++
		console.log(`函数内部调用${count}次`)
	}
	return fun
}
const result = fn();
result() //2
result() //3
// 1、result是一个全局变量,代码执行完毕不会立即销毁
// 2、result可以找到fn()函数,fn()函数return fun(),因此 fun()也不会销毁。
// 3、fun()引用到了父级作用域的count,因此,在引用的count便不会被垃圾回收机制回收。
// 此时,闭包就引起了内存泄漏问题
// 正常情况下,一般的局部变量函数执行完就会销毁,但是我们这里的result没有销毁,所以它引用到的count也会留存在内存当中。

闭包的应用

函数工厂

function makeAdder(x) {
   return function(y) {
     return x + y;
   };
 }

 var add5 = makeAdder(5);
 var add10 = makeAdder(10);

 console.log(add5(2));  // 7
 console.log(add10(2)); // 12

模拟私有方法

 var makeCounter = function () {
   var privteCounter = 0;
   function changeBy(val) {
     privteCounter += val;
   }
   return {
     increment: function () {
       changeBy(1);
     },
     decrement: function () {
       changeBy(-1);
     },
     value: function () {
       return privteCounter;
     },
   };
 };

 var Counter1 = makeCounter();
 var Counter2 = makeCounter();
 console.log(Counter1.value()); /* logs 0 */
 Counter1.increment();
 Counter1.increment();
 console.log(Counter1.value()); /* logs 2 */
 Counter1.decrement();
 console.log(Counter1.value()); /* logs 1 */
 console.log(Counter2.value()); /* logs 0 */

标签:闭包,function,console,函数,count,JS,理解,return
From: https://www.cnblogs.com/fishlittle/p/17355108.html

相关文章

  • 01_JS技巧
    1.判断对象数据类型示例代码如下constisType=(type)=>(target)=>`[object${type}]`===Object.prototype.toString.call(target)constisArray=isType('Array')constisObject=isType('Object')constisBoolean=isType('......
  • 理解 Java8 的时间API(二)时间
    理解Java8的时间API:java.time上一篇介绍了Java8里新的时区API。这一篇介绍新的时间API:LocalDateTime,LocalDate,LocalTime类。三、Java8中的时间最常用的应该是java.time.LocalDateTime,java.time.LocalDate,java.time.LocalTime,java.time.Instant这几个类。3.1LocalDateTim......
  • unity发布到4399的webgl模式问题:FRAMEWORK.JS中的WEBREQUEST_SEND括号内的函数(不能有
    在发布4399的时候,之前遇到过这个问题,解决方法当然就是删除这个函数啦。步骤也很简单,但是刚开始摸不着头脑搞了好久,最后发现发布的时候有个加密选项,选择不加密,后面build的文件里面就可以进行打开修改,按照要求修改函数即可。......
  • 项目实践:我在嵌入式控制上对PID算法的理解
    关于PID算法的碎碎念(我也不知道咋说明)。笔者:czg-bky全文:我在嵌入式控制上对PID算法的理解-czg-bky-博客园(cnblogs.com)......
  • Three.js#04#Responsive Design&Scenegraph
    参考https://threejs.org/manual/#en/responsive和https://threejs.org/manual/#en/scenegraph前者主要是说怎样创建一个响应式的three.js应用,就是在变化屏幕大小的时候,画面不会畸形。后者是再说,怎么组合小的组件变成一个大的组件(依赖于一个空组件object3D)下面是示例代码:index.......
  • ngxin 配置 二级目录使用nodejs处理
    ngxin配置location/napi{proxy_passhttp://127.0.0.1:7018;proxy_set_headerHost$host:$server_port;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_h......
  • 将ansible的输出转换为JSON格式
    第一步找到ansible.cfg我的ansible.cfg的文件在/etc/ansible文件夹的下面。可以使用Linux命令行进行切换到这个文件夹下面。cd/etc/ansible第二步,修改ansible.cfg文件,在配置文件中添加以下的配置。[defaults]stdout_callback=jsonbin_ansible_callbacks=True ......
  • js 复制/转换 window对象的全部属性内容 为字符串
    控制台copy(window)不行,只得到[objectWindow]copy(object) copiesastringrepresentation至于具体是怎么实现的嘛,猜测类似于.toString() ofthespecifiedobjecttotheclipboard.(参考https://developer.chrome.com/docs/devtools/console/utilities/#copy-function) co......
  • 彻底理解 cookie、session、token
    发展史1、很久很久以前,Web基本上就是文档的浏览而已,既然是浏览,作为服务器,不需要记录谁在某一段时间里都浏览了什么文档,每次请求都是一个新的HTTP协议,就是请求加响应,尤其是我不用记住是谁刚刚发了HTTP请求,每个请求对我来说都是全新的。这段时间很嗨皮。2、但是随着交互式We......
  • Vue.js 简介与入门指南
    Vue.js是一个轻量级的JavaScript框架,用于构建交互式的用户界面。Vue.js的核心是一个用于构建组件化应用的视图层库,它易于上手,且能够快速地构建出高效、灵活、易于维护的应用程序。Vue.js受到了许多开发者的欢迎,因为它允许使用简单的HTML模板来创建可重用的组件,这些组件可以......