闭包

*比如我们通过js构建一个商品对象,初始化传入商品ID。 
该对象里面有个方法,该方法假设要通过『有逼格』的计算才能获获取商品名称*

1.

<script type="text/javascript">
    var product = function(id){
        var prodID = id;
        this.prodName = "药品"; //这个属性外部可以访问

        function loadProd(){ //这个方法不希望外部访问
            //假设这个过程需要复杂的计算
            if (prodID == 1) {
                this.prodName = "霸王油";
            }else if (prodID == 2) {
                this.prodName = "老鼠药";
            }
        }
    }

    var p1 = new product(1);
    alert(p1.prodName); //打印:药品
</script>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

并没有获取到我们认为的『霸王油』, 这是因为实例化后的p1并不能调用loadProd这个方法。

2.所以我们只能在内部调用

var product = function(id){
        var prodID = id;
        this.prodName = "药品"; //这个属性外部可以访问

        function loadProd(){ //这个方法不希望外部访问
            //假设这个过程需要复杂的计算
            if (prodID == 1) {
                this.prodName = "霸王油";
            }else if (prodID == 2) {
                this.prodName = "老鼠药";
            }
        }

        loadProd(); //内部调用啦
    }

    var p1 = new product(1);
    alert(p1.prodName); //打印:药品
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

上面代码还是弹出『药品』,这是因为loadProd()函数内部的this并不是我们传入的。 
优化:

var product = function(id){
        var prodID = id;
        this.prodName = "药品"; //这个属性外部可以访问

        function loadProd(oo){ //这个方法不希望外部访问
            //假设这个过程需要复杂的计算
            if (prodID == 1) {
                oo.prodName = "霸王油";
            }else if (prodID == 2) {
                oo.prodName = "老鼠药";
            }
        }

        loadProd(this); //传入this
    }

    var p1 = new product(1);
    alert(p1.prodName); //打印:霸王油

    var p2 = new product(2);
    alert(p2.prodName); //打印:老鼠药
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

3.闭包的写法

    var product = function(id){
        var prodID = id;
        var prodName = "药品"; 

        function loadProd(){ //这个方法不希望外部访问
            //假设这个过程需要复杂的计算
            if (prodID == 1) {
                prodName = "霸王油";
            }else if (prodID == 2) {
                prodName = "老鼠药";
            }

            return prodName; // 返回私有变量
        }

        return loadProd; //返回函数本身
    }

    var p1 = new product(1);
    alert(p1()); //p1() 就是执行了loadProd(),结果打印:霸王油
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

再次优化:

    var product = function(id){
        var prodID = id;
        var prodName = "药品"; 

        return function loadProd(){ //这个方法不希望外部访问
            //假设这个过程需要复杂的计算
            if (prodID == 1) {
                prodName = "霸王油";
            }else if (prodID == 2) {
                prodName = "老鼠药";
            }
            return prodName; // 返回私有变量
        }
    }

    var p1 = new product(1);
    alert(p1()); //结果打印:霸王油
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

简单总结: 
1.内部function访问了外部变量 
2.内部函数维持了外部函数(对象)的数据 
3.闭包本身是为了简化代码、减少过多的人工细节参与

<script type="text/javascript">
    var product = function(id){
        var prodID = id;
        var prodName = "药品"; 

        return function loadProd(){ //这个方法不希望外部访问
            //假设这个过程需要复杂的计算
            if (prodID == 1) {
                prodName = prodName + "霸王油"; // 内部函数也可以使用外部函数的数据
            }else if (prodID == 2) {
                prodName = prodName +"老鼠药";
            }
            return prodName; // 返回私有变量
        }
    }

    var p1 = new product(1);
    alert(p1()); //结果打印:药品霸王油
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值