2015-04-21 60 views
0

我有我創建瞭如下一個基本庫:重寫toString方法 - 公共/私有訪問

(function() { 
    function Store() { 
     var store = []; 

     if (!(this instanceof Store)) { 
      return new Store(); 
     } 

     this.add = function (name, price) { 
      store.push(new StoreItem(name, price)); 
      return this; 
     }; 
    } 

    function StoreItem(name, price) { 
     if (!(this instanceof StoreItem)) { 
      return new StoreItem(); 
     } 

     this.Name = name || 'Default item'; 
     this.Price = price || 0.0; 
    } 

    Store.prototype.toString = function() { 
     // build a formatted string here 
    }; 

    StoreItem.prototype.toString = function() { 
     return this.Name + ' $' + this.Price; 
    }; 

    window.shop = window.shop || { 
     Store: function() { 
      return new Store(); 
     } 
    }; 
}()); 

絕大多數的這個效果很好!但是,我不想公開我在Store構造函數中定義的store數組,因爲我不希望它在此庫的控件之外被修改。

但是,相反,我想重寫StoretoString方法使store陣列中使用StoreItem S的,所以我可以返回使用其toString方法的所有StoreItem s的格式化字符串。

E.g.如果store被曝光後,toString方法看起來是這樣的:

Store.prototype.toString = function() { 
    return this.store.join('\r\n'); 
}; 

// shop.Store().add('Bread', 2).add('Milk', 1.5).toString() result: 
// Bread $2 
// Milk $1.5 

反正我能做到這一點沒有公開暴露我的store陣列?

回答

2

你可以給每個Store它自己的.toString方法,是特權通過關閉訪問本地store變量 - 就像你.add做:

function Store() { 
    if (!(this instanceof Store)) { 
     return new Store(); 
    } 
    var store = []; 

    this.add = function(name, price) { 
     store.push(new StoreItem(name, price)); 
     return this; 
    }; 
    this.toString = function() { 
     return store.join('\n'); 
    }; 
} 

或者,你必須定義某種訪問的方法,或者你的store將是無用的,如果你只能添加到它,但從來沒有讀過它。有些東西需要顯示商店項目,需要迭代它們,需要測試它們的可用性......如果創建一個通用訪問器,或許以某種迭代器的形式(一個帶回調的each方法?),然後使用.prototype.toString方法也可以使用它。

+0

我沒有得到這個...什麼可以阻止我做這樣的事情:var bla = new Store(); bla.toString; < - 包含函數... – OddDev

+0

@OddDev:那又如何?該函數不是'store'數組。 OP想要隱藏'store',而不是'toString'方法。 – Bergi

+0

加1 - 這似乎是最簡單的方法。 – MrCode

1

可以保留原型toString方法,同時保護store,方法是添加一個返回字符串的store並從Store.prototype.toString調用它的公共方法。

下面我將this.getStoreString添加到構造函數中,並從原始的toString中調用它。

(function() { 
    function Store() { 
     var store = []; 

     if (!(this instanceof Store)) { 
      return new Store(); 
     } 

     this.add = function (name, price) { 
      store.push(new StoreItem(name, price)); 
      return this; 
     }; 

     // new method 
     this.getStoreString = function(){ 
      return store.join('\r\n'); 
     }; 
    } 

    function StoreItem(name, price) { 
     if (!(this instanceof StoreItem)) { 
      return new StoreItem(); 
     } 

     this.Name = name || 'Default item'; 
     this.Price = price || 0.0; 
    } 

    Store.prototype.toString = function() { 
     // call the new method 
     return this.getStoreString(); 
    }; 

    StoreItem.prototype.toString = function() { 
     return this.Name + ' $' + this.Price; 
    }; 

    window.shop = window.shop || { 
     Store: function() { 
      return new Store(); 
     } 
    }; 
}()); 

Fiddle

@ BERGI的答案似乎簡單不過,但是這顯示了另一種選擇。