[英]Creating an object with privacy and prototyping(templating) similar to C++ class-private
**編輯 - 這在答案中沒有明確說明......但是你不能擁有“模板化(即不為每個實例復制)”的私有成員而沒有自動執行功能。 您將支付處理器時間和代碼復雜性以保護隱私
像C ++私有類成員一樣。
我一直在努力確定什么樣的“hack”用於創建類似乎有超過10種人們定義類的方式。
我正在尋找的類的類型提供隱私和模塊化以及模板機制。 Javascript有原型來創建這個模板機制。 但是我目前使用的解決方案沒有私人成員。
如果沒有,我不得不問這個問題,如果我將所有的javascript移動到這個類類型,那么成本是多少...其中每個都是自執行函數? 現在,當我的代碼加載它時,必須先運行它才能使用它。
這個成本是更好的編程實踐的折衷。 現在我有適當的隱私課程。
成本值得嗎? 額外的運行時間值得隱私嗎?
以下是一些類似的問題:
目前的方法 - 缺乏隱私......散布出來...... 不包括在parantheses中
var Message = function( div )
{
this.div = document.getElementById( div );
};
Message.prototype.messages =
{
name: 'Please enter a valid name',
email: 'Please enter a valid email',
pass: 'Please enter passoword, 6-40 characters',
url: 'Pleae enter a valid url',
title: 'Pleae enter a valid title',
tweet: 'Please enter a valid tweet',
empty: 'Please complete all fields',
same: 'Please make emails equal',
taken: 'Sorry, that email is taken',
validate: 'Please contact <a class="d" href="mailto:support@host.com">support</a> to reset your password'
};
Message.prototype.display = function( type )
{
Control.sendInner( this.div, this.messages[type] );
};
Javascript有原型來創建這個模板機制。 但是我目前使用的解決方案沒有私人成員。
我所知道的使用原型和私有狀態的唯一機制是WeakMaps。
這基本上涉及在原型范圍內具有本地WeakMap
免責聲明: WeakMaps是ES6 ,我相信目前只有firefox 6有一個實現 ,但是它們可以是shimmed
var Message = (function() {
var map = new WeakMap();
var Message = function(div) {
var privates = {};
map.set(this, privates);
privates.div = document.getElementById(div);
};
Message.prototype.messages = {
name: 'Please enter a valid name',
email: 'Please enter a valid email',
pass: 'Please enter passoword, 6-40 characters',
url: 'Pleae enter a valid url',
title: 'Pleae enter a valid title',
tweet: 'Please enter a valid tweet',
empty: 'Please complete all fields',
same: 'Please make emails equal',
taken: 'Sorry, that email is taken',
validate: 'Please contact <a class="d" href="mailto:support@host.com">support</a> to reset your password'
};
Message.prototype.display = function(type) {
var privates = map.get(this);
Control.sendInner(privates.div, this.messages[type]);
};
return Message;
}());
需要注意的是WeakMaps是ES6,並且有一個顯著的計算開銷從weakmap獲取對象,而再從this
。
使用文章中提到的klass
實用程序,代碼如下所示:
var Message = klass(function(privates) {
return {
constructor: function(div) {
privates(this).div = document.getElementById(div);
},
messages: {
name: 'Please enter a valid name',
email: 'Please enter a valid email',
pass: 'Please enter passoword, 6-40 characters',
url: 'Pleae enter a valid url',
title: 'Pleae enter a valid title',
tweet: 'Please enter a valid tweet',
empty: 'Please complete all fields',
same: 'Please make emails equal',
taken: 'Sorry, that email is taken',
validate: 'Please contact <a class="d" href="mailto:support@host.com">support</a> to reset your password'
},
display = function(type) {
Control.sendInner(privates(this).div, this.messages[type]);
}
};
});
再次使用privates(this).x
而不是this.x
具有兩個函數調用的計算開銷。 這不應該被忽視。
還要注意,使用weakmaps比使用閉包具有更少的內存開銷,因為你仍然使用原型進行函數並且只使用弱映射進行狀態。
成本值得嗎? 額外的運行時間值得隱私嗎?
就個人而言,我說“隱私”的運行時間懲罰是需要進行基准測試的。 計算開銷很小,內存使用開銷也很小。
所以,我使用的形式是這樣的:
var Message = function (div) {
this.div = document.getElementById(div);
// messages will be 'private'
var messages = { 'name' : 'Please enter ...' }; // You get the picture here
this.display = function (type) {
Control.sendInner(this.div, messages);
}
}
您可以在對象范圍標題下的這篇文章中閱讀有關私有,靜態和公共變量的更多信息。
更新:您還可以使用嚴格模式並設置不可寫變量或僅限getter值。 盡管如此,您可能希望這不受支持,並且可能會使您在編寫代碼方面更加嚴格。
在您的構造函數中,您在該函數中聲明的任何變量實際上都是私有的 - 它僅限於該實例,即:
var Message = function( div )
{
var private = "hello, world!";
this.div = document.getElementById( div );
};
但是,這些變量非常私密,無法從您隨后添加到原型的函數中訪問它們。
訪問它們的唯一方法是通過所謂的“特權法”,作為財產造成即那些this
對象內部 。
除非通過使用變量的范圍規則,否則我認為JavaScript中不存在任何隱私。 但這並不總是意味着立即調用的函數表達式。 您可以使用構造函數范圍的變量與構造函數分配的方法相結合,如下所示:
function YourConstructor() {
var private1 = 0,
private2 = 'spock';
this.count = function () { return private1++; }
this.chiefOfficer = function (name) {
if(name) private2 = name;
return private2;
}
}
即使你在定義YourConstructor
之前執行代碼, YourConstructor
發生前向聲明魔術並且一切都很好( 注意 :發布的其他一些解決方案使用var YourConstructor = function () {...
idiom - 這些都行不通在需要前方聲明的情況下)。
這有一個問題:每次調用構造函數時,都要定義構造函數指定的方法(而不是一次分配給原型)。 在您創建大量這些對象的情況下,可能會有性能/內存命中。
但是,關於隱私的一句話:我邀請您考慮一下這樣的觀點,即大多數時候,通過運行時強制機制對隱私的需求被高估了。
為什么? 開發人員有很多事情要做; 在所有的可能性,他們很可能寧可不要注意任何給定的抽象的內部,除非它泄漏有毒的東西。
不會導致問題的類,拋出/返回有用的錯誤,提供真正有用的方法,你可以調用它來完成任務(對很多getter和setter!),並且記錄得很好......這些類可能不會需要任何類型的隱私執行機制,因為每個人都會對你的課程拯救他們的工作感到高興,他們不會在里面同行。
對於不符合該標准的類,缺乏隱私執行機制可能不是真正的問題。
有一個例外:有時候(特別是在可以通過網絡瀏覽的網頁上),您可以使用不受信任的來源與您的代碼混合。 在一種非常動態的語言(如JavaScript)中,您可能希望在外部代碼無法訪問的地方隔離/隱藏某些功能。 但是,如果您不擔心這一點,您可能希望花更多時間通過良好的設計和文檔來鼓勵實施隱藏/隱私,而不必擔心技術執行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.