对于需要保存在this构造函数中的值,我有哪些选择可以实现隐私?例如一个简单的Stack实现:
function Stack(){
this._stack = {}
this._counter = 0
}
Stack.prototype.push = function (item){
this._stack[this._counter++] = item
return this
}
Stack.prototype.pop = function (){
Reflect.deleteProperty(this._stack, --this._counter);
return this
}
Stack.prototype.peek = function (){
return this._stack[this._counter - 1]
}
Stack.prototype.length = function (){
return Object.values(this._stack).length
}
Run Code Online (Sandbox Code Playgroud)
如果这些方法没有定义为原型方法,我可以像这样轻松地私有它们:
function Stack(){
let _stack = {}
let _counter = 0
this.push = function (item){
_stack[_counter++] = item
return this
}
this.pop = function (){
Reflect.deleteProperty(_stack, --_counter);
return this
}
this.peek = function (){
return _stack[_counter - 1]
}
this.length = function (){
return Object.values(_stack).length
}
}
Run Code Online (Sandbox Code Playgroud)
这种方式_stack并_counter没有暴露出来,但是这些方法不在原型链上。
是否有可能实现隐私,而受保护的值保存在this?
这是使用私有字段的示例。您可以使用static关键字将它们设为静态,但这在本示例中不是必需的。
class test {
#lol = 29;
#mas = 15;
constructor() {
this.#lol++;
this.#mas--;
return {
value: this.#lol - this.#mas
};
}
};
console.log(new test().value); // --> 16Run Code Online (Sandbox Code Playgroud)
MDN 在其Keyed 集合指南中提供了私有属性的示例。
弱映射对象
对象
WeakMap是键/值对的集合,其中键只是对象,值可以是任意值。键中的对象引用被弱保留,这意味着如果不再有其他对该对象的引用,它们将成为垃圾收集 (GC) 的目标。APIWeakMap与API相同Map。与对象的一个区别
Map是WeakMap键不可枚举(即,没有方法为您提供键列表)。如果是的话,列表将取决于垃圾收集的状态,从而引入非确定性。有关更多信息和示例代码,另请参阅“为什么是弱映射?” 在参考页上
WeakMap。对象的一种用例
WeakMap是存储对象的私有数据,或隐藏实现细节。以下示例来自 Nick Fitzgerald 的博客文章“使用 ECMAScript 6 WeakMaps 隐藏实现细节”。私有数据和方法属于对象内部并存储在对象中。实例和原型上暴露的所有内容都是公开的;其他一切都无法从外部世界访问,因为没有从模块导出。privatesWeakMapprivatesRun Code Online (Sandbox Code Playgroud)const privates = new WeakMap(); function Public() { const me = { // Private data goes here }; privates.set(this, me); } Public.prototype.method = function () { const me = privates.get(this); // Do stuff with private data in `me`... }; module.exports = Public;
应用于您的场景,这可能如下所示:
const Stack = (function () {
const privates = new WeakMap();
function Stack() {
privates.set(this, { stack: {}, counter: 0 });
}
Stack.prototype.push = function (item) {
const _ = privates.get(this);
_.stack[_.counter++] = item;
return this;
};
Stack.prototype.pop = function () {
const _ = privates.get(this);
Reflect.deleteProperty(_.stack, --_.counter);
return this;
};
Stack.prototype.peek = function () {
const _ = privates.get(this);
return _.stack[_.counter - 1];
};
Stack.prototype.length = function () {
const _ = privates.get(this);
return Object.values(_.stack).length;
};
return Stack;
})();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
212 次 |
| 最近记录: |