深入理解js的闭包问题&实现单例模式

为什么js会产生闭包

这其实是跟js的作用域有关系的,举个例子:

        function out() {
            var x=123
            function inner() {
                var y=456
                console.log(x)//123
            }
            return inner
        }
        var res=out()
        res()

首先,out函数的调用和inner函数的生成是同一阶段的,调用了out函数才会产生定义inner函数。显然,inner函数可以访问到x,如果在out函数内部调用inner,肯定能打印出x的值。那么,为什么将inner函数返回出去,再在外边调用,仍然能够访问到x呢?
原因在于作用域链,这里存在两条作用域链,由于out函数调用时产生了inner函数,所以这两个函数都分别有一条自己的作用域链,当out函数执行完毕之后,它的作用域链就断掉了,但此时inner的还在,所以即便out函数被销毁,inner仍然能够访问out里边定义的变量,由此就产生了闭包。

js的防抖与节流,其实也都是闭包的一个应用。

利用闭包实现单例模式

什么叫单例模式?
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例—来自360百科
关于单例模式更详细的解释,这里暂且不提。
现在,假设要做一个登录功能,因为页面中能触发弹出登录框的按钮可能不止一个,而我们需要保证每个按钮触发的弹框是同一个框。

        // 闭包实现单例模式--登录功能
        var login=function(){
            var div=document.createElement('div')
            div.innerHTML='登录'
            // 隐藏登录框
            div.style.display='none'
            document.body.appendChild(div)
            return div;
        }
        var single=function(fn){
            var result
            // 闭包
            return function(){
                return result||(result=fn.apply(this,arguments))
            }
        }
        var create=single(login)
        document.getElementById('loginBtn').onclick=function(){
            var loginLay=create()
            loginLay.style.display='block'
        }

捋一下代码:
var create=single(login),把login函数当作实参传递到了single函数中,会返回一个匿名函数;var loginLay=create(),create的调用就是上边匿名函数的调用,它会返回一个result给loginLay,第一次执行时,result值为undefined,而 || 的作用就是,把fn的返回值给到result,所以此时的result就是登录的div,而当多次触发按钮的点击事件时,result仍然是上次点击时的那个div,这样就防止了登录div被重复创建。
这段功能的闭包体现在,create是single函数返回出去的一个函数,即使single函数被销毁,create仍然能访问result的值。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值