昨天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
歡迎關注個人微信公衆號:老虎的小窩