Есть ли способ использовать скрытие информации, не тратя впустую память в прототипах Javascript?
Я следую руководству Крокфорда по частным методам в Javascript и борюсь с чем-то. Я пытаюсь оптимизировать этот код
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
this.service = function () {
return dec() ? that.member : null;
};
}
путем определения функций вне конструктора, чтобы новый объект функции не создавался при каждом создании нового экземпляра.
Я до сих пор не знаю, как это сделать для тех, кого он называет частными (любая помощь приветствуется). Для тех, кого он называет привилегированными методами, это то, что я пытаюсь сделать:
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
}
Container.prototype.service = function() {
return dec() ? that.member : null;
};
но если я проверю это так
d1 = new Container("content");
d1.service();
Я получаю эту ошибку:
ReferenceError: dec is not defined
Означает ли это, что нельзя использовать преимущества закрытых / привилегированных методов, которые использует Крокфорд И оптимизировать использование памяти, связывая все экземпляры класса с одним и тем же функциональным объектом? Я надеюсь, что вы докажете, что я неправ.
1 ответ
Если вы не хотите создавать новый dec
на каждый звонок Container
, ты можешь сделать Container
в IIFE - определить dec
когда Container
определяется, а затем вернуть фактический Container
конструктор из IIFE, так что dec
можно ссылаться только изнутри Container
, Инкапсулировать secrets
, использовать Map
индексируется экземпляром вместо использования простого var secrets
в конструкторе, так что (общий) dec
а также service
функции могут видеть и использовать карту.
На самом деле, как отмечается в комментариях, вероятно, было бы лучше использовать WeakMap, чтобы связанный с экземпляром секрет можно было собирать мусором после того, как экземпляр GC'd:
const Container = (() => {
const secretsByInstance = new WeakMap();
function dec(instance) {
const secret = secretsByInstance.get(instance);
if (secret > 0) {
secretsByInstance.set(instance, secret - 1);
return true;
} else {
return false;
}
}
function Container(param) {
secretsByInstance.set(this, 3);
this.member = param;
}
Container.prototype.service = function() {
return dec(this) ? this.member : null;
};
return Container;
})();
d1 = new Container("content");
console.log(d1.service());
console.log(d1.service());
console.log(d1.service());
console.log(d1.service());