闭包closure

news/2024/6/18 21:44:01 标签: js

闭包closure

  • 一、引例
    • 1、n++函数
    • 2、把n放外面
    • 3、改成闭包
  • 二、例子
    • 1、点击按钮增加
    • 2、li绑定事件
  • 三、关闭

一、引例

1、n++函数

function closure() {
     let n=1
     n++
     console.log(n);
 }
 closure()  //2
 closure()  //2
 closure()  //2
 closure()  //2

2、把n放外面

 let n=1
 function closure() {            
     n++
     console.log(n);
 }
 closure() //2
 closure() //3
 closure() //4
 closure() //5

把n放外面,成为全局变量,缺点是会影响全局

3、改成闭包

function closure() {
    let n=1           
    function child() {
        n++
    }
    console.log(n);
}
let myClosure=closure()  // 接收closure返回值
console.log(myClosure);  // undefined
function closure() {
    let n=1           
    function child() {
        n++
        console.log(n);
    }
}
closure()  //无返回
closure()  //无返回
closure()  //无返回

执行了closure() ,但是里面的child()不执行,这种写法不知道什么意思?

function closure() {
      let n=1           
      return function child() {
          n++
          console.log(n);
      }
  }
  let myClosure=closure()  // 接收closure返回值
  console.log(myClosure);  
  //myClosure 返回 ƒ child() {
                n++
                console.log(n);
            }

再执行myClosure()

function closure() {
     let n=1           
     return function child() {
         n++
         console.log(n);
     }
 }
 let myClosure=closure()
 myClosure()  //2
 myClosure()  //3
 myClosure()  //4

n的值被保存在内存中,保存在该js内存里面开辟的小块新内存中,等于该js文件内存里可以开辟更多的内存空间,互不影响独立的空间。感觉是在网页内引入多个js文件的child版本

二、例子

1、点击按钮增加

知乎上看到的这个例子https://www.zhihu.com/question/19554716

<body>
    <button id="add">1</button>  
    <span id="span">1</span> 
    <script>
    (function (){  
        var val = 1;  
        add.onclick = function (){  
            val++;  
            span.innerHTML = val;  
        }          
    })()  // 自执行匿名函数      
    </script>
</body>

(1)例子中,去掉自执行匿名函数,也是正常运行的,只不过val变成全局变量
(2)获取dom元素不是let add=document.getElementById(‘add’),然后再add.onclick?

<button id="add">1</button>  
<span id="span">1</span> 
<script>
    console.log(add); // <button id="add">加1</button>
    var val = 1;  
    add.onclick = function (){  
        val++;  
        span.innerHTML = val;  
    }             
</script>

在Chrome的JavaScript终端中,你只需要输入一个元素的ID,就可以访问到这个元素?
https://www.cnblogs.com/jiangxiaobo/p/6061745.html

2、li绑定事件

https://zhuanlan.zhihu.com/p/87950150

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
  </ul>
<script>
   let li=document.getElementsByTagName('li')
   li.forEach(element => {
       console.log(element); //forEach不遍历类数组  //li.forEach = Array.prototype.forEach;
   });
</script>
<script>
   let li=document.getElementsByTagName('li')
   for(let ele of li){
       console.log(ele);  //for of可以遍历数组/类数组/字符串/Set和Map
   }
</script>

打印li内容

let li=document.getElementsByTagName('li')
    for(let ele of li){
        ele.onclick=()=>{
            console.log(ele.innerHTML); // 点击li可以打印li的内容
        }
    }

打印li的索引

<script>
   let li=document.getElementsByTagName('li')
   for (let i = 0; i < li.length; i++) {
       li[i].onclick=()=>{
           console.log(i);
       }          
   }
</script>  // 可以正常打印索引

当我把let i改为var i 后

<script>
   let li=document.getElementsByTagName('li')
   for (var i = 0; i < li.length; i++) {
       li[i].onclick=()=>{
           console.log(i);
       }          
   }
</script>  // 点击li打印的i都为5

为什么?为什么?为什么?

<script>
   let li=document.getElementsByTagName('li')
   for (var i = 0; i < li.length; i++) {
       li[i].onclick=()=>{
           console.log(i);
       }          
   }
   li[0].onclick()  //5    //吃惊
</script>

for循环结束后,i的值为5,每个li点击事件console.log(i)中的i都为5

<script>
   let li=document.getElementsByTagName('li')
   for (var i = 0; i < li.length; i++) {
       li[i].onclick=()=>{
           console.log(i);
       }          
   }
   console.log(i);  //5
   li[0].onclick()  //5
</script>

改为let

<script>
   let li=document.getElementsByTagName('li')
   for (let i = 0; i < li.length; i++) {
       li[i].onclick=()=>{
           console.log(i);
       }          
   }
   console.log(i);  // 报错,i未定义
   li[0].onclick()
</script>
<script>
    let li=document.getElementsByTagName('li')
    for (let i = 0; i < li.length; i++) {
        li[i].onclick=()=>{
            console.log(i);
        }          
    }
 //    console.log(i);
    li[0].onclick() //0
 </script>

在var下的for循环,相当于

<script>
   let li=document.getElementsByTagName('li')
   {
       var i=0
       li[i].onclick=()=>{
           console.log(i);
       }
   }
   {
       var i=1
       li[i].onclick=()=>{
           console.log(i);
       }
   }
   {
       var i=2
       li[i].onclick=()=>{
           console.log(i);
       }
   }
</script>

而let是有作用域的,相当于有了个闭包?
把var包装成闭包,例子,不知道实用不,let不是可以很好解决吗?

<script>
   let li=document.getElementsByTagName('li')
   for (var i = 0; i < li.length; i++) {
       li[i].onclick=function(i){
           return ()=> {                  
            console.log(i);
           }             
       }(i)          
   }
</script>

三、关闭

function closure() {
  let n = 1;
  return function child() {
    n++;
    console.log(n);
  };
}
let myClosure = closure();
myClosure(); //2
myClosure(); //3
myClosure(); //4
myClosure=null   // 关闭
myClosure = closure();  // 打开
myClosure(); //2

http://www.niftyadmin.cn/n/1409600.html

相关文章

电脑编程入门_公明楼村UG编程培训,零基础可以学会的吗?

随着社会的进步和科技的昌明发达&#xff0c;当今社会没有一门技术是行不通的&#xff0c;顺应社会的发展的步伐学一门技术才是明智之举&#xff0c;模具数控行业是当前工业发展前景比较好的行业。我是零基础的&#xff0c;在厂里做开机员好多年了&#xff0c;因为要上夜班&…

从输入一个URL到页面渲染的流程简介

首先说明以下是我参考网上答案和自己的思考&#xff0c;给出自己的想法&#xff0c;如果有问题&#xff0c;欢迎大家吐槽从用户在浏览器中输入一个URL&#xff0c;到整个页面渲染&#xff0c;这个过程中究竟发生了什么呢&#xff1f;今天先简单写下整个过程&#xff0c;后面再一…

提供一批ip供另外一个局域网做互通_演播室IP信号视频传输解决方案

演播室是电视节目制作的常规基地&#xff0c;演播室的节目制作过程中&#xff0c;大部分是摄像机与制作中心使用SDI视频线连接。视频传输需要的带宽和线缆问题愈发突出&#xff0c;电视台现有的以SDI基带视频接口和专用SDI数字视频矩阵为基础的技术架构已难以满足。随着融合媒体…

More-iOS国际化一站式解决方案

title: More-iOS国际化一站式解决方案 date: 2018-04-10 21:10:40 tags: iOS国际化关于iOS开发中的国际化&#xff08;也可称为多语言&#xff09;在网上的文章多如牛毛&#xff0c;不过总结起来就那么一回事&#xff0c;不是说他们写的不好我写的多好&#xff0c;而是说过于零…

id3决策树 鸢尾花 python_30分钟理解决策树的基本原理

文章发布于公号【数智物语】 (ID&#xff1a;decision_engine)&#xff0c;关注公号不错过每一篇干货。来源 | Python与算法之美(ID&#xff1a;Python_Ai_Road)作者 | 梁云1991决策树是一种非参数的监督学习方法&#xff0c;它主要用于分类和回归问题。决策树模型通过一系列if…

Flutter路由传参

Flutter路由传参1、普通路由2、路由拦截onGenerateRoute1、普通路由 //main.dart routes: routes,// 路由跳转 onTap: () {// 跳转到任务详情页Navigator.of(context).pushNamed(taskDetail,arguments:listViewData[index]); },// 接收参数&#xff0c;在Widget中 Text(ModalR…

TCP/IP基础总结性学习(4)

返回结果的 HTTP 状态码 一.简单介绍&#xff1a; 总述&#xff1a;HTTP 状态码负责表示客户端 HTTP 请求的返回结果、标记服务器端的处理是否正常、通知出现的错误等工作。状态码构成&#xff1a;以 3 位数字和原因短语组成。数字中的第一位指定了响应类别&#xff0c;后两位无…

xgboost算法_手把手机器学习实战系列:xgboost 算法

算法简介xgboost算法是一种boosting的集成学习算法&#xff0c;是将多个弱学习模型进行组合&#xff0c;从而获得更好的效果&#xff0c;使得组合后的模型有更强的泛化能力&#xff0c; 它通常是由基本的回归树(CART)树模型组成如图所示:通过输入用户的年龄&#xff0c;性别来判…