昨天QT给个人一个功能提了一个bug。大概意思就是说,一段在不一样位置都会被调用的代码,在A处被调用的时候,彷佛会对其余调用的地方产生影响。javascript
我仔细debug了半天,终于找到了缘由。简化过的代码以下:html
1 function C(name, id){ 2 this.name = name; 3 var privateId = id; 4 if (typeof this.showName != "function") { 5 C.prototype.showName = function(){ 6 console.log(this.name); 7 } 8 C.prototype.showId = function(){ 9 console.log(privateId); 10 } 11 } 12 13 } 14 15 var c1 = new C('name1', 'id1'); 16 var c2 = new C('name2', 'id2'); 17 18 c1.showName(); //name1 19 c1.showId(); //id1 20 c2.showName(); //name2 21 c2.showId(); //id1 !!!!
问题出在最后一行,c2的showId方法打印出了id1。java
苦思冥想良久,终于让我想到了问题的缘由——c2对象在调用构造函数的时候,不会进入if分支里面!微信
为何呢?由于c1在实例化的时候,this.showName = undefined,因而进入if分支,给本身的prototype加上了一个showName方法一个showId方法。闭包
等到c2对象实例化的时候,this.showName已经再也不是undefined了,因而不会进入if分支。函数
这样,c2的showId方法和c1的showId方法是同一个方法,并且这个方法里面打印的privateId变量则都是c1在实例化的时候建立的那个变量,也就是id1。测试
因此效果就是,原本想把privateId变量申明成一个私有变量,但这样写了以后,它变成了一个static变量了,真是缘木求鱼,南辕北辙啊。this
问题缘由找到了,那么如何求解呢?spa
个人思路是,要使用闭包实现私有变量,那么这个闭包的函数就要与须要隐藏的变量绑定起来。而私有变量又是和类的实例绑定的,也就是c1和c2分别有本身的私有变量,因此闭包函数也必须和类的实例一一绑定。因而就改为了这样:prototype
1 function C(name, id){ 2 this.name = name; 3 var privateId = id; 4 if (typeof this.showName != "function") { 5 C.prototype.showName = function(){ 6 console.log(this.name); 7 } 8 9 } 10 11 this.showId = function(){ 12 console.log(privateId); 13 } 14 }
经测试,结果是正确的。
不过我依然在怀疑,我上面说的思路中“闭包的函数就要与须要隐藏的变量绑定起来”这一句,是不是正确的?若是是否,那么还有没有其余的更好的方式实现这个需求呢?
如需转载,请注明转自:http://www.cnblogs.com/silenttiger/p/3443375.html
欢迎关注个人微信公众号:老虎的小窝