闭包

概念

闭包就是能够读取其他函数内部变量的函数,在本质上是函数内部和函数外部链接的桥梁

特点:

不会触发垃圾回收机制,自由变量跨作用域取值时,要去创建这个函数的作用域取值,而不是“父作用域”

缺点:

可能会造成内存泄漏

常见情况:

你只需要知道应用的两种情况即可——函数作为返回值,函数作为参数传递。如果函数作为参数传递 或者 返回值是一个函数 一般都是闭包。

应用:

  • 函数防抖
    demo:
    // 防抖
    const debounce = (fn, wait)=> {    
        let timeout;    
        return ()=> {        
            // 每当用户触发事件的时候把前一个 setTimeout clear 掉
            clearTimeout(timeout);        
            // 然后又创建一个新的 setTimeout, 这样就能保证wait 间隔内如果时间持续触发,就不会执行 fn 函数
            timeout = setTimeout(()=>{fn()}, wait);    
        }
    }
    // 处理函数
    const handle = ()=> {    
        console.log(`防抖:${Math.random()}`); 
    }
    // 滚动事件
    window.addEventListener('scroll', debounce(handle, 1000));
  • 封装私有变量  
    function Person() {
        var name = 'Eric' //私有属性,通过实例对象不能访问
    
        this.getName = function() {
            return name;
        }
        this.setName = function(value) {
            name = value
        }
    }
    Person.prototype = {
        getNameTest() {
            return this.name;
        },
    }
    
    let p = new Person()
    console.log(p.getName()) // Eric
    p.setName('Amy')
    console.log(p.getName()) //Amy
    
    //直接通过实例对象访问
    console.log(p.name) // undefined
    
    //通过原型上的方法访问时
    console.log(p.getNameTest())// undefined
  • 解决for循环变量相互影响的问题

demo 目标:想要依次打印0-9

for(var i = 0; i < 10; i++){
    setTimeout(()=>console.log(i),0)
}
// 实际控制台输出了10遍10.

用闭包解决

for(var i = 0; i < 10; i++){
    (function(a){
    setTimeout(()=>console.log(a),0)
    })(i)
}
 // 控制台输出0-9

 

posted @ 2020-10-22 11:32  菜鸟小何  阅读(223)  评论(0编辑  收藏  举报