经典js闭包题

下面是自己积累的几道经典JS闭包题

每一道都很有代表性,可能有的题解释的不到位,大家可以参考着结果先自己想一想,如果能够把这几道闭包题搞清楚,那么你在函数闭包上的成长一定是很大的

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <script type="text/javascript">
        //代码片段一
        var name = "The Window";
        var object = {
            name: "My Object",
            getNameFunc: function() {
                return this.name;
                return function() {
                    return this.name;
                };
            }
        };
        console.log(object.getNameFunc()); //My Object 对象的方法的this指向的是对象本身

        //代码片段二
        var name2 = "The Window";
        var object2 = {
            name2: "My Object",
            getNameFunc: function() {
                return function() {
                    return this.name2;
                };
            }
        };
        console.log(object2.getNameFunc()()); //The Window
        //对象的方法里的函数, 不管套了多少层, 都只是普通函数, 都指向window

        //代码片段三
        function fun(n, o) {
            console.log(o)
            return {
                fun: function(m) {
                    return fun(m, n)
                }
            }
        }

        var a = fun(0); //undefined
        a.fun(1); //0
        a.fun(2); //0
        a.fun(3); //0

        var b = fun(0).fun(1).fun(2).fun(3); //undefined 0 1 2

        var c = fun(0).fun(1); //undefined 0
        c.fun(2); //1
        c.fun(3); //1
        //这道题实在太多经典,如果能把这道题的运行过程搞懂,那么闭包,你见到其他题,应该都没问题了
        //由于这道题的运行过程是在过于繁琐,不在这里多讲,大家先自己试着运行一下,实在还有问题的话,我再好好讲一下,
        //如果自己能够运行明白的话,对于自己在闭包上的成长绝对是很大的

        //代码片段四
        function Foo() {
            getName = function() {
                alert(1);
            }
            return this;
        }
        Foo.getName = function() {
            alert(2);
        }
        Foo.prototype.getName = function() {
            alert(3);
        }
        var getName = function() {
            alert(4);
        }

        function getName() {
            alert(5);
        }
        //请写出以下输出结果:
        Foo.getName(); //2 Foo当对象调用getName方法,答案很明显是输出2
        getName(); //4 直接调用getName函数,这里有两个,最后两个都是,不过按顺序执行,所以输出4
        Foo().getName(); //1 调用Foo函数,并执行getName函数,明显输出1,
        //不过值得注意的是,Foo函数return this,由于Foo里的getName函数没有带var,直接把全局的getName函数给修改了,
        //所以现在全局的getName函数的值已经变成了1
        getName(); //1 现在再调用getName,值已经变为1
        new Foo.getName(); //2 注意!!!这里的new完全是一个烟雾弹,就是用来迷惑人的,其实还是Foo当对象调用getName方法输出2
        new Foo().getName(); //3 这里才是new一个Foo实例,并调用实例的getName方法,由于自身没有,会去原型对象身上找,输出的是3
        new new Foo().getName(); //3 这里的两个new,第一个new,没有任何作用,因为它和它后面的new不能执行,只能让后面new先去执行,
        //我们发现后面的new能够执行,和上一个执行结果是一样的,至于第一个new,实际上没有什么意义

        //代码片段五
        var Counter = (function() {
            var privateCounter = 0;

            function changeBy(val) {
                privateCounter += val;
            }
            return {
                increment: function() {
                    changeBy(1);
                },
                decrement: function() {
                    changeBy(-1);
                },
                value: function() {
                    return privateCounter;
                }
            }
        })();
        console.log(Counter.value()); //0 调用value打印1
        Counter.increment(); //执行changeBy函数,结果为1
        Counter.increment(); //再次执行changeBy函数,结果为2
        console.log(Counter.value()); //2 现在调用value,因为闭包的存在,自身没有,向上找,此时privateCounter的值为2
        Counter.decrement(); //再次执行changeBy函数,结果为1
        console.log(Counter.value()); //1 因为闭包的存在,自身没有,向上找,此时privateCounter的值为1

        //代码片段六
        var makeCounter = function() {
            var privateCounter = 0;

            function changeBy(val) {
                privateCounter += val;
            }
            return {
                increment: function() {
                    changeBy(1);
                },
                decrement: function() {
                    changeBy(-1);
                },
                value: function() {
                    return privateCounter;
                }
            }
        };
        var Counter1 = makeCounter(); //这是两个独立的闭包它俩之间没有任何关系
        var Counter2 = makeCounter(); //这是两个独立的闭包它俩之间没有任何关系
        console.log(Counter1.value()); //0
        Counter1.increment(); //1
        Counter1.increment(); //2
        console.log(Counter1.value()); //2
        Counter1.decrement(); //1
        console.log(Counter1.value()); //1
        console.log(Counter2.value()); //0
    </script>
</body>
</html>
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值