JS闭包笔记

闭包

是一种特性,由作用域和垃圾回收机制共同作用而出现的一种特性。
是指有权访问另一个函数作用域中的变量的函数。
建闭包的常见方式:就是在一个函数内部创建另一个函数。
本质上,闭包是将函数内部和函数外部连接起来的桥梁。
闭包的特点:

  • 作用域空间不销毁
    优点:因为不销毁,变量也不会销毁,增加了变量的生命周期
    缺点:因为不销毁,会一直占用内存,多了以后就会导致内存溢出
  • 可以利用闭包访问在一个函数外部访问函数内部的变量
    优点:可以再函数外部访问内部数据
    缺点:必须要时刻保持引用,导致函数执行栈不被销毁
  • 保护私有变量
    优点:可以把一些变量放在函数里面,不会污染全局
    缺点:要利用闭包函数才能访问,不是很方便
var scope = "window scope"; 
function checkScope() {
     var scope = "local scope"; 
     function f() {
         return scope; 
    } 
     return f();
  } 
checkScope(); //=> "local scope"

checkScope被invoke时,return f(),运行内部嵌套函数f,f沿着作用域链从内向外寻找变量scope,
找到“local scope”,停止寻找,因此,函数返回 “local scope”;
var scope = "window scope"; 
function checkScope() {
     var scope = "local scope"; 
     function f() {
         return scope; 
    } 
     return f;
  } 
checkScope()(); //=> "local scope"
	* 
checkScope被invoke时,将内部嵌套的函数f返回,因此checkScope()()这句执行时,其实运行的是f(),f函数返回scope变量。
	* 
*词法作用域的基础规则*:函数被执行时(executed)使用的作用域链(scope chain)是被定义时的scope chain,而不是执行时的scope chain。
   嵌套函数f(), 被定义时,所在的作用域链中,变量scope是被绑定的值是“local scope”,而不是"window scope",因此,以上代码的结果是"local scope"。 
        这就是闭包的神奇*特性*:闭包可以捕获到局部变量和参数的外部函数绑定,即便外部函数的调用已经结束。
var scope = "window scope"; 
function checkScope() {
     var scope = "local scope"; 
     function f() {
         return this.scope; 
    } 
     return f;
  } 
checkScope()(); //=> "window scope"
闭包的this指向的是它定义的地方的this,非严格模式下,函数内部的this指向全局对象
(严格模式下,this为undefined),函数 checkScope 的this指向的是window对象,所以返回了window scope
闭包的应用场景

1.为节点循环绑定click事件

<body>
    <button>Button0</button>
    <button>Button1</button>
    <button>Button2</button>
    <button>Button3</button>
    <button>Button4</button>
    <script>
        let btnList = document.querySelectorAll("button");
        for(var i = 0;i<btnList.length;i++){
            //错误的代码 onclick是异步触发的,
            // btnList[i].onclick = function(){
            //     console.log(i)
            // }
        
            //正确的代码
            //采用“立即执行函数Immediately-Invoked Function Expression (IIFE)”的方式创建作用域
            (function(i){
                btnList[i].onclick = function(){
                    console.log(i)
                }
            })(i);
        }
    </script>
</body>
  1. 延续局部变量的寿命
<script>
        var report = (function() {
            var imgs = [];
            return function(src) {
                var img = new Image();
                imgs.push(img);
                img.src = src;
            }
        })()


        (function(){
            //i在外部就不认识啦
            for(var i=0;i<count;i++){}
        })();
        console.log(i);//报错,无法访问
</script>        

3.对结果进行缓存

<script>
        var fn=function(){
            var sum=0;
            for(var i=0;i<arguments.length;i++){
                    sum+=arguments[i];
            }
            return sum;
        }
        console.log(fn(1,2));//3
        
        //优化版本
        var fn=(function(){
            var cache={}//将结果缓存到该对象中
            return function(){
                var str=JSON.stringify(arguments);
                if(cache[str]){//判断缓存中是否存在传递过来的参数,存在直接返回结果,无需计算
                    return cache[str];
                }else{//进行计算并返回结果
                    var sum=0;
                    for(var i=0;i<arguments.length;i++){
                        sum+=arguments[i];
                    }
                    return cache[str]=sum;
                }
            }
        })();
        console.log(fn(3,8));//11
</script>

4.设计模式之 构造器模式

<script>
        // 构造器模式
        function Car(model, year, miles){
            this.model = model;
            this.year = year;
            this.miles = miles;

            Car.prototype.toString = function(){
                return this.model + ' has done ' + this.miles + ' miles';
            }
        }
        var civic = new Car('honda civic', 2019, 2000);
        console.log(civic);
        console.log(civic.toString());
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值