前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >js 闭包

js 闭包

作者头像
用户4793865
发布2023-01-12 16:01:11
2.2K0
发布2023-01-12 16:01:11
举报
文章被收录于专栏:前端小菜鸡yym前端小菜鸡yym

这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战

闭包三个特性

  1. 函数内嵌套函数
  2. 函数内部可以引用函数外部的参数和变量
  3. 参数和变量不会被垃圾回收机制回收

闭包的形式

1. 函数作为返回值

代码语言:javascript
复制
function a(){
    var name = 'dev';
    return function(){    //是一个匿名函数  函数运行都是由内部向外部
      return name;
    }
}
var b = a();
console.log(b()); // dev
console.log(b)    //  function(){ return name;}

下面例子 n没有形成闭包,而num形成了闭包(在匿名函数内部去调用了外部函数的变量)。num没有被垃圾回收机制回收,而n被垃圾回收机制回收了。所以每次调用fn1() 都是1

代码语言:javascript
复制
function fn(){
    var num = 3;
    return function(){
        var n = 0;
        console.log(++n);
        console.log(++num);
    }
}
var fn1 = fn();
fn1();  // 1 4  
fn1();  // 1 5

2.定时器与闭包

(1) 输出的结果是5次5,那么为什么那?因为js是单线程的,在执行for循环的时候定时器被安排到任务队列中排队等待执行,而在等待的过程中,for循环就已经执行了。等到setTimeout可以执行的时候,for循环已经结束,i的值也已经编程了。(异步等待同步队列执行完毕再执行)

代码语言:javascript
复制
for(var i=0;i<5;++i){

    setTimeout(function(){

      console.log(i);

    },100)

}

(2)将 var i 换为 let i

代码语言:javascript
复制
for(let i=0;i<5;++i){

    setTimeout(function(){

      console.log(i);

    },100)

}      //  1 2 3 4 5

执行结果是我们想要的 1 2 3 4 5。

因为var 定义的变量是全局作用域,有变量提升的作用。循坏每一次执行都是将值赋值给全局变量

代码语言:javascript
复制
for(var i =0;i<5;i++){

}
console.log(i);    // 5

let是块级作用域,只能在代码块内起作用。一个大括号是一个代码块,每次for循环都会产生一个代码块。每次代码块中都是新的变量

代码语言:javascript
复制
for(let j = 0;j<5;j++){

 }   
console.log(j)   // 报错 j is not defined

3.闭包来实现输出 1 2 3 4 5

代码语言:javascript
复制
for(var i=0;i<5;i++){

 (function(i){

    setTimeout(function(){

  console.log(i);

},i**100) //每隔100s执行一次**

})(i)    //i作为参数并立即执行**
}

几个涉及到的小知识

代码语言:javascript
复制
立即执行函数
(function a(){alert(11);})()
代码语言:javascript
复制
● 函数声明

function a(){}  // 使用 function 关键字,并指定一个函数名*

● 函数表达式

var name = fucntion(){}  //使用function关键字声明一个函数,但未给函数命名,最后将匿名函数赋予给一个变量。

typeof name    // string

console.log(name)  // fucntion(){}

● 匿名函数

function(){};   //使用function关键字声明一个函数,但未给函数命名*

4.闭包作为参数传递*

代码语言:javascript
复制
var num = 15;
var fn1 = function(x){
    if(x>num){
    console.log(x)
      }

}

void function(fn2){
    var num = 100;
    fn2(30);
}(fn1)    // fn2 此时是形参,实参是fn1*

fn1作为参数传入立即执行函数中,在执行到fn2(30)的时候,30作为参数传入fn1中(fn1作为参数传入,也就变为 void function(fn1){var num = 100; fn1(30);})。   接着30作为参数传入fn1中,这时if(x>num)中的num取的并不是立即执行函数中的num,而是创建函数的作用域中的num 15。 30>15 ,打印15

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-11-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 闭包三个特性
  • 闭包的形式
    • 1. 函数作为返回值
      • 2.定时器与闭包
        • 3.闭包来实现输出 1 2 3 4 5
          • 几个涉及到的小知识
            • 4.闭包作为参数传递*
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档