onclick如何调用含参函数_如何讲清楚闭包?

8fb995729d8b6df450e14de2a27496ce.png

我们都知道一个概念。

在JS当中,一个函数可以访问其外部的变量资源。

0b3e1b9e6719c9c97a1cec3ea561ad99.png
一个典型的代码

但以下这种情况会出错。

function m1(){
    var a = 100;
    console.log(a++);
}

function m2(){
    console.log(a++);   //这里无法访问a
}

如果,我们想在m2的作用域里,访问m1里的变量,就像下面这样:

7d2b1cc24fa36af44280f1136e2baa05.png

首先,我们可以在m1的内部创建一个函数m3

function m1(){
    var a = 100;
    function m3(){
        console.log(a++);
    }
}

8d1e8e1f6e0d007e54b596f8163e981e.png

m3可以正常访问a,接下来我们增加一个return操作。

function m1(){
    var a = 100;
    return function m3(){
        console.log(a++);
    }
}

既然有了返回值,那我们不妨接收一下,继续编写代码如下:

function m1(){
    var a = 100;
    return function m3(){
        console.log(a++);
    }
}
var _m3 = m1();

我们执行了函数m1, 并将返回值赋值给_m3

那么目前_m3m3函数是等价的,即它们是同一个函数。

有了_m3,一切都好办了。我们继续编写代码

function m1(){
    var a = 100;
    return function m3(){
        console.log(a++);
    }
}
var _m3 = m1();

function m2(){
    _m3();
}

因为_m3是全局变量,因此m2可以调用_m3

也就等价于m2间接的,访问到了变量a

543e804c6c12b624b7944fa7e2aa9788.png

通常,我们管m3,叫做一个『 闭包函数 』

下面列举几个常见的闭包场景:

01

for(var i=0; i<list.length; i++){
    var item = list[i];
    item.onclick = (function(num){
        return function(){
            //......
        }
    })(i);
} 

02

function (){
    var that = this;
    setTimeout(function(){
        //......
    },2000)
}

03

function User(){
    var _age = 0;
    this.getAge = function(){
        return _age;
    }
    this.setAge = function(age){
        this._age = age;
    }
}

04

(function(){
    var cache = [...];
    return {
        get : function(){
            //...
        }
    };
})()

05

(function(){
    var t = null;
    return function(){
        if(!t){
            t = create();
        }
    }
})()


为了创造闭包,有时候会写函数自调用

可以不这么麻烦么??

当然,那就是使用let。

例如

for(let i=0; i<list.length; i++){
    let item = list[i];
    item.onclick = function(){
        console.log(i);
        //观察变量i的值  
    };
} 
 

关于闭包的疑问

当函数m1执行完成的时候,内部的变量a,理论上应该被回收掉了。

2f351cce01caf2430b2eade69393bf27.png

可是为什么变量a依然可以被访问呢?

主要是因为,m3还在引用它

a2767bde6f7544d89171303d627c9625.png

垃圾回收器显然不会回收一个依然被引用的变量。

除非这个变量,已经无人引用,即是说,它已经无法再内存里被找到。

此时才可以当做垃圾处理。

不过m3可以访问变量a这种规则,并不是在所有编程语言里都生效的。因此,这也算是JS的特性之一。

千锋HTML5学院:如何讲清楚this指向?​zhuanlan.zhihu.com
e36e943275789bee36101fe37f8ff34a.png
千锋HTML5学院:如何讲清楚Redux的概念?​zhuanlan.zhihu.com
1de875302c4d716ba8146e3d6fc68662.png
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值