首页 > 闭包定义在对象中的问题

闭包定义在对象中的问题

看犀牛书关于闭包的相关章节,看到一个关于闭包的问题,对结果不是十分理解

function counter() {
    var n =0;
    return {
        count:function() {return n++;},
        reset:function() {n=0;}
        };
        }
var c = counter(), d = counter();
c.count()                           //0
d.count()                           //0
c.reset()
c.count()
d.count()

对 第二个0不是太理解,为什么同一对象下的方法可以共享一个状态n,另一个对象共享的是另一个状态n,感觉不管哪个对象下方法定义的函数的内部[[scope]]都是一样的,为什么不是一起共享状态n呢?


因为你实例化了2个不同的对象

console.log(c === d); // false

function counter() {
    var n = 0;
    return {
        count: function() {
            return n++;
        },
        reset: function() {
            n = 0;
        }
    };
}
var c = counter(),
    d = counter();
console.log(c === d)//false 其实c和d是两个对象。

c.count() //0
d.count() //0
c.reset()
c.count()
d.count()

c对象的n和d对象的n其实是不同的。

var c = counter(), d = counter();

将counter方法运行了两遍,其中的作用域是不同的。
如果想让c,d共享一个变量,counter方法可以这么写:

var counter =  (function () {
    var m = 0;//这个是共享的变量;
    return function(){
        var n =0;//每次执行后的都不相干涉,类似对象的私有变量;
        return {
            classCount : function(){return m++;},
            classCountReset : function(){m=0},
            count:function() {return n++;},
            reset:function() {n=0;}
            };
        };
     })();
var c = counter(), d = counter();
c.count();                           //0
d.count();                           //0
c.classCount();                      //0
d.classCount();                      //1
c.classCount();                      //2
c.reset();
c.count();                           //0
d.count();                           //1
c.classCountReset();
c.classCount();                      //0
d.classCount();                      //1
c.classCount();                      //2

感觉不管哪个对象下方法定义的函数的内部[[scope]]都是一样的。

是不对的。

你要知道,同一个函数,每调用一次,都会生成新的上下文和词法环境。例子里调用了两次,生成的是两个独立的词法环境,以及独立的n。所以c.count和d.count的[[scope]]属性是不同的。

画了一个图:

图中的圆角矩形代表词法环境(global以及每次函数调用时生成的)。


翻看犀牛书,仔细看了上面的例子:我的理解如下图,:

图画的有点不好但意思理解就好
也就是说每次调用一次函数,都会创建一个新的作用域链和一个新的私有变量,因此,那两个不同的对象调用,会有不同的结果。希望我理解的可以帮助你理解。

【热门文章】
【热门文章】