javascript
es6 类的私有属性_JavaScript ES6类中的私有属性
要擴展@loganfsmyth的回答:
JavaScript中唯一真正私有的數據仍然是作用域變量。不能以與公共屬性相同的方式在內部訪問私有屬性,但是可以使用范圍變量來存儲私有數據。
作用域變量
這里的方法是使用構造函數的作用域(它是私有的)來存儲私有數據。要使方法能夠訪問這些私有數據,它們也必須在構造函數中創建,這意味著您要用每個實例重新創建它們。這是一個性能和內存的懲罰,但一些人認為這個懲罰是可以接受的。可以避免對不需要訪問私有數據的方法進行懲罰,方法可以像往常一樣將它們添加到原型中。
例子:function?Person(name)?{
let?age?=?20;?//?this?is?private
this.name?=?name;?//?this?is?public
this.greet?=?function?()?{
//?here?we?can?access?both?name?and?age
console.log(`name:?${this.name},?age:?${age}`);
};}let?joe?=?new?Person('Joe');joe.greet();//?here?we?can?access?name?but?not?age
作用域WeakMap
WeakMap可以用來避免先前方法的性能和內存損失。WeakMaps將數據與對象(此處為實例)關聯起來,使其只能使用該WeakMap進行訪問。因此,我們使用作用域變量方法創建私有WeakMap,然后使用該WeakMap檢索與this..這比作用域變量方法更快,因為所有實例都可以共享一個WeakMap,因此您不需要僅僅為了使它們訪問自己的WeakMaps而重新創建方法。
例子:let?Person?=?(function?()?{
let?privateProps?=?new?WeakMap();
class?Person?{
constructor(name)?{
this.name?=?name;?//?this?is?public
privateProps.set(this,?{age:?20});?//?this?is?private
}
greet()?{
//?Here?we?can?access?both?name?and?age
console.log(`name:?${this.name},?age:?${privateProps.get(this).age}`);
}
}
return?Person;})();let?joe?=?new?Person('Joe');joe.greet();//?here?we?can?access?joe's?name?but?not?age
本例使用一個對象對多個私有屬性使用一個WeakMap;您還可以使用多個WeakMaps,并使用它們如下age.set(this, 20),或者編寫一個小包裝并以另一種方式使用它,如privateProps.set(this, 'age', 0).
從理論上講,這種方法的隱私可能會被篡改全球的行為所破壞。WeakMap對象。也就是說,所有的JavaScript都可能被破損的全局破壞。我們的代碼已經建立在這樣的假設之上。
(這個方法也可以用Map,但是WeakMap更好是因為Map除非您非常小心,否則將產生內存泄漏,為此目的,兩者在其他方面并沒有什么不同。)
半答案:限定范圍的符號
符號是一種可以用作屬性名稱的原語值類型。可以使用作用域變量方法創建私有符號,然后將私有數據存儲在this[mySymbol].
此方法的隱私可能會被侵犯Object.getOwnPropertySymbols,但做起來有點尷尬。
例子:let?Person?=?(function?()?{
let?ageKey?=?Symbol();
class?Person?{
constructor(name)?{
this.name?=?name;?//?this?is?public
this[ageKey]?=?20;?//?this?is?intended?to?be?private
}
greet()?{
//?Here?we?can?access?both?name?and?age
console.log(`name:?${this.name},?age:?${this[ageKey]}`);
}
}
return?Person;})();let?joe?=?new?Person('Joe');joe.greet();//?Here?we?can?access?joe's?name?and,?with?a?little?effort,?age.?ageKey?is
//?not?in?scope,?but?we?can?obtain?it?by?listing?all?Symbol?properties?on//?joe?with?`Object.getOwnPropertySymbols(joe)`.
半答案:下劃線
舊的默認值,只需使用帶有下劃線前綴的公共屬性。盡管在任何情況下都不是私有財產,但這種約定非常普遍,因此它很好地傳達了讀者應該將該財產視為私有財產,這通常會使工作完成。作為交換,我們得到了一種更容易閱讀、更容易打字和更快的方法。
例子:class?Person?{
constructor(name)?{
this.name?=?name;?//?this?is?public
this._age?=?20;?//?this?is?intended?to?be?private
}
greet()?{
//?Here?we?can?access?both?name?and?age
console.log(`name:?${this.name},?age:?${this._age}`);
}}let?joe?=?new?Person('Joe');joe.greet();//?Here?we?can?access?both?joe's?name?and?age.?But?we?know?we?aren't
//?supposed?to?access?his?age,?which?just?might?stop?us.
結語
截至2017年,私人地產仍沒有完美的做法。各種方法各有優缺點。作用域變量是真正的私有變量;作用域WeakMaps非常私有,比作用域變量更實用;作用域符號具有合理的私有性和合理的實用性;下劃線通常具有足夠的私有性和非常實用性。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的es6 类的私有属性_JavaScript ES6类中的私有属性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: B+树 -- MySQL数据库索引
- 下一篇: java shiro security_