看犀牛书关于闭包的相关章节,看到一个关于闭包的问题,对结果不是十分理解
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以及每次函数调用时生成的)。
翻看犀牛书,仔细看了上面的例子:我的理解如下图,:
图画的有点不好但意思理解就好
也就是说每次调用一次函数,都会创建一个新的作用域链和一个新的私有变量,因此,那两个不同的对象调用,会有不同的结果。希望我理解的可以帮助你理解。